本文共--字 阅读约--分钟 | 浏览: -- Last Updated: 2021-12-21
/** query请求时,url参数拼接 */
function addUrlParam(url: string, name: string, value: string): string {
let newUrl = url;
newUrl += (url.indexOf('?') === -1 ? '?' : '&');// 没有?加? 有问号加&
newUrl += `${encodeURIComponent(name)}=${encodeURIComponent(value)}`;
return newUrl;
}
/** xhr请求入参 */
export interface RequestOptions {
url: string;
method: string;
params?: Record<string, any>;
data?: Record<string, any>;
timeout?: number;
headers?: Record<string, any>;
dataType?: XMLHttpRequestResponseType;
}
export function xhr(options: RequestOptions): Promise<any> {
const xhr = new XMLHttpRequest();
return new Promise((resolve, reject) => {
const {
url, method, timeout, data = {}, headers, dataType,
} = options;
let newUrl = url;
xhr.responseType = dataType || 'json';
xhr.timeout = timeout || 10000;
xhr.withCredentials = true;
// 处理GET参数拼接
if (method.match(/get/i)) {
if (options.params) {
Object.keys(options.params).forEach((key: string) => {
newUrl = addUrlParam(newUrl, key, options.params?.[key]);
});
}
}
xhr.open(method.toLowerCase(), newUrl);
// 处理请求头
if (headers) {
Object.keys(headers).forEach((key: string) => {
xhr.setRequestHeader(key, headers[key]);
});
}
// 处理超时
xhr.ontimeout = function onTimeout() {
reject(new Error('timeout'));
};
// 处理请求中断
xhr.onabort = function onAbort() {
reject(new Error('XMLHTTPRequest abort'));
};
// 处理请求错误
xhr.onerror = function onError() {
reject(new Error('XMLHTTPRequest error'));
};
// 处理请求完成
xhr.onload = function onLoad() {
if ((xhr.status >= 200 && xhr.status <= 300) || xhr.status === 304) {
resolve(xhr.response);
} else {
reject(new Error('status error'));
}
};
try {
// 处理post请求体
if (method.match(/post/i)) {
xhr.setRequestHeader('Content-Type', 'application/json');
xhr.send(JSON.stringify(data));
} else {
// eslint-disable-next-line no-null/no-null
xhr.send(null);
}
} catch (error) {
reject(new Error('network error'));
}
});
}