UNPKG

ych-pumpkin

Version:
121 lines (108 loc) 3.61 kB
import 'whatwg-fetch'; import { jsonToFormData, jsonToUrlEncode, getEncodeUrl, fetchJsonp } from './proRequest.config'; const formatBody = (body, reqDataType) => { switch (reqDataType) { case 'formdata': return jsonToFormData(body); case 'json': return JSON.stringify(body); case 'text': return JSON.stringify(body); case 'form': return jsonToUrlEncode(body); default: return JSON.stringify(body); } }; const getContentType = (reqDataType) => { switch (reqDataType) { case 'json': return { 'Content-Type': 'application/json' }; case 'text': return { 'Content-Type': 'text/plain' }; case 'form': return { 'Content-Type': 'application/x-www-form-urlencoded' }; default: return {}; } }; const setAjaxHeader = (xhr, config) => { if (config.headers) { for (const key in config.headers) { xhr.setRequestHeader(key, config.headers[key]); } } }; const ajax = ({ url, body, type, reqDataType, onProgress, timeout, config, }) => new Promise((resolve, reject) => { const xhr = new XMLHttpRequest(); xhr.onload = e => resolve(JSON.parse(e.target.responseText)); xhr.onerror = reject; if (xhr.upload && onProgress) { xhr.upload.onprogress = e => onProgress(Math.floor(e.loaded * 100 / e.total), e); } if (type === 'post') { xhr.open(type, url); setAjaxHeader(xhr, config); xhr.send(formatBody(body, reqDataType)); } else if (type === 'get') { xhr.open(type, getEncodeUrl(url, body)); setAjaxHeader(xhr, config); xhr.send(); } setTimeout(() => { reject(); }, timeout); }); const getByJsonp = ({ url, body, timeout }) => Promise.race([fetchJsonp(getEncodeUrl(url, body)), new Promise((resolve, reject) => { setTimeout(() => { reject(); }, timeout || 10000); })]).then(response => response.json(), () => { throw new Error('网络超时'); }); const requestByFetch = (url, option, timeout) => { let time = null; return Promise.race([fetch(url, option), new Promise((resolve, reject) => { time = setTimeout(() => { reject({ from: 'caoh5-request:requestByFetch', message: '网络异常', }); }, timeout); })]).then((response) => { clearTimeout(time); if (response.status === 200 || (response.status >= 550 && response.status <= 560)) { return Promise.all([response.json(), new Promise((resolve, reject) => { resolve(response.status); })]).then(values => Object.assign({}, values[0], { HTTP_CODE: values[1] })); } throw new Error(response.statusText); }); }; const getByFetch = ({ url, body, config, timeout, }) => requestByFetch(getEncodeUrl(url, body), Object.assign({ method: 'get', }, config), timeout); const postByFetch = ({ url, body, reqDataType, config, timeout, }) => { config.headers = { ...config.headers, ...getContentType(reqDataType) }; return requestByFetch(url, Object.assign({ method: 'post', body: formatBody(body, reqDataType), }, config), timeout); }; const proRequest = (params) => { const { url, type = 'get', dataType = 'json', onProgress, timeout = 10000, config = {}, body = {}, } = params; const reqDataType = dataType.toLowerCase(); if (onProgress) { return ajax({ url, type, body, reqDataType, onProgress, timeout, config, }); } else if (type === 'jsonp') { return getByJsonp({ url, body, timeout }); } if (type === 'get') { return getByFetch({ url, body, config, timeout, }); } else if (type === 'post') { return postByFetch({ url, body, reqDataType, config, timeout, }); } }; export { proRequest };