UNPKG

fetch-plugin

Version:

fetch polyfill with TIMEOUT setting and other options, extend from whatwg-fetch

183 lines (151 loc) 5.33 kB
import 'whatwg-fetch' let globalHeaders = { "Content-Type": "application/json" } let globalOption = { headers: new Headers(globalHeaders), mode: "same-origin", credentials: "include", cache: "reload", redirect: "follow", timeout: 30000, fetchStart(param) { return param } } let mergeOptions = (...args) => { let myOptions = Object.assign({}, ...args) let resultHealers = Object.assign({}, globalHeaders, myOptions.headers) let resultOptions = null resultOptions = Object.assign({}, globalOption, myOptions) resultOptions.headers = new Headers(resultHealers) return { resultOptions, resultHealers } } let setOptions = (options) => { globalOption = mergeOptions(options).resultOptions globalHeaders = mergeOptions(options).resultHealers } let parseJSON = (response) => { const maxErrorRes = 500 return response.text().then((text) => { try { return JSON.parse(text) } catch (err) { throw new Error(`JSON Parse Error: ${err}, URL: ${response.url}, ${text.slice(0, maxErrorRes)}`) } }) } let checkStatus = (response) => { if ((response.status >= 200 && response.status < 300) || response.status == 304) { return response } else { throw new Error(`HTTP Status Code: ${response.status}, URL: ${response.url}`) } } let setGetURL = (url, data = {}) => { if (Object.prototype.toString.call(data) !== "[object Object]" || Object.keys(data).length === 0) { return url } let list = [] for (let key in data) { list.push(`${encodeURIComponent(key)}=${encodeURIComponent(data[key])}`) } return url + (url.indexOf("?") === -1 ? "?" : "") + list.join("&") } let getJSON = (url, data = {}, option = {}) => { let fetchOption = mergeOptions({ method: "GET" }, option).resultOptions let fetchURL = setGetURL(url, data) return _fetch(fetchURL, fetchOption) .then(parseJSON).then(handleFetchPass, handleFetchError) } let deleteJSON = (url, data = {}, option = {}) => { let fetchOption = mergeOptions({ method: "DELETE" }, option).resultOptions let fetchURL = setGetURL(url, data) return _fetch(fetchURL, fetchOption) .then(parseJSON).then(handleFetchPass, handleFetchError) } let postJSON = (url, data = {}, option = {}) => { let fetchOption = mergeOptions({ method: "POST", body: JSON.stringify(data) }, option).resultOptions let fetchURL = url return _fetch(fetchURL, fetchOption) .then(parseJSON).then(handleFetchPass, handleFetchError) } let putJSON = (url, data = {}, option = {}) => { let fetchOption = mergeOptions({ method: "PUT", body: JSON.stringify(data) }, option).resultOptions let fetchURL = url return _fetch(fetchURL, fetchOption) .then(parseJSON).then(handleFetchPass, handleFetchError) } let handleFetchPass = (data) => { typeof globalOption.fetchSuccess === "function" && globalOption.fetchSuccess(data) return data } let handleFetchError = (error) => { typeof globalOption.fetchError === "function" && globalOption.fetchError(error) error = error instanceof Error ? error : new Error(error) throw error } let getJSONP = (url, data = {}, option = {}) => { let callbackValue = "jsonp" + +new Date() let jsonpElement = document.createElement("script") data[option.callbackName || "_callback"] = callbackValue let fetchURL = setGetURL(url, data) let head = document.head || document.querySelector("head") || document.documentElement jsonpElement.setAttribute("src", fetchURL) jsonpElement.setAttribute("charset", "utf-8") jsonpElement.setAttribute("defer", true) jsonpElement.setAttribute("async", true) head.insertBefore(jsonpElement, head.firstChild) return new Promise((resolve, reject) => { window[callbackValue] = (payload) => { resolve(payload) head.removeChild(jsonpElement) } jsonpElement.onerror = () => { reject() head.removeChild(jsonpElement) } }) } let _fetch = (url, fetchOption) => { return new Promise((resolve, reject) => { let timer = 0 Promise.resolve(fetchOption.fetchStart({ url, fetchOption })).then((param) => { if (param === false) { let error = new Error(`${param.url} cancel`) error.fetchOption = param.fetchOption reject(error) } let myRequest = new Request(param.url, param.fetchOption) timer = setTimeout(() => { let error = new Error(`${param.url} timeout`) error.fetchOption = param.fetchOption reject(error) }, param.fetchOption.timeout) return fetch(myRequest) }).then((response) => { clearTimeout(timer) response.fetchOption = fetchOption resolve(response) }, (error) => { clearTimeout(timer) error.url = url error.fetchOption = fetchOption reject(error) }) }).then(checkStatus) } export default { setOptions, getJSONP, getJSON, postJSON, putJSON, deleteJSON }