ych-pumpkin
Version:
121 lines (108 loc) • 3.61 kB
JavaScript
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 };