這一小節,主要是把異常的處理加上
處理錯誤
網絡錯誤
就在你發送 Ajax 請求的地方,new 出來的 XMLHttpRequest 有一個 onerror
的方法,把你的方法掛上去就可以了。
request.onerror = function handleError() {
reject(new Error('Network Error'));
}
超時錯誤
同樣的,在new 出來的 XMLHttpRequest 有一個 ontimeout
的方法,把你的方法掛上去就可以了。
if(timeout) request.timeout = timeout; // timeout 是可選的
request.ontimeout = function handleTimeout() {
reject(new Error(`Timeout of ${timeout} ms exceeded`));
}
其他錯誤
response.status 在 [200,300) 之間,就表明請求成功,否則就表示錯誤。以下這個函數是放在 onreadystatechange
函數的最後來進行處理。
function handleResponse(response: AxiosResponse) : void{
if(response.status >= 200 && response.status < 300) {
reslove(response);
} else {
reject(new Error(`Request failed with status code ${response.status}`));
}
}
更加詳盡的錯誤信息
這個其實就是構造函數
import {AxiosRequestConfig,AxiosResponse} from '../types';
export class AxiosError extends Error {
isAxiosError: boolean
config: AxiosRequestConfig
code?: string|null
request?:any
response?:AxiosResponse
constructor(
message:string,
config:AxiosRequestConfig,
code?: string|null,
request?:any,
response?: AxiosResponse,
){
super(message);
this.config = config;
this.code = code;
this.request = request;
this.response = response;
this.isAxiosError = true;
Object.setPrototypeOf(this,AxiosError.prototype);
}
}
export function createError(
message:string,
config:AxiosRequestConfig,
code?: string|null,
request?:any,
response?: AxiosResponse,
) {
return new AxiosError(message,config,code,request,response);
}
在之前使用 new Error() 的,都改成 createError
函數
完整的代碼,這裏只寫一些改變了的代碼,按照之前的目錄結構,我會在 helpers
中新建立一個 error.ts
文件
import {AxiosRequestConfig,AxiosResponse} from '../types';
export class AxiosError extends Error {
isAxiosError: boolean
config: AxiosRequestConfig
code?: string|null
request?:any
response?:AxiosResponse
constructor(
message:string,
config:AxiosRequestConfig,
code?: string|null,
request?:any,
response?: AxiosResponse,
){
super(message);
this.config = config;
this.code = code;
this.request = request;
this.response = response;
this.isAxiosError = true;
Object.setPrototypeOf(this,AxiosError.prototype);
}
}
export function createError(
message:string,
config:AxiosRequestConfig,
code?: string|null,
request?:any,
response?: AxiosResponse,
) {
return new AxiosError(message,config,code,request,response);
}
types/index.ts
中就添加了一個結構 AxiosError
:
/...
export interface AxiosError extends Error {
isAxiosError: boolean,
config: AxiosRequestConfig,
code?: string | null,
request?:any;
response?:AxiosResponse,
}
還有 xhr.ts
改變過:
import {AxiosRequestConfig,AxiosPromise,AxiosResponse} from './types';
import {parseHeaders} from './helpers/header';
import {createError} from './helpers/error';
export default function xhr(config:AxiosRequestConfig) : AxiosPromise {
return new Promise((reslove,reject)=> {
const {data = null,url,method='get',timeout,headers,responseType} = config;
const request = new XMLHttpRequest();
if(responseType) request.responseType = responseType;
// 超時操作
if(timeout) request.timeout = timeout;
request.onreadystatechange = function handleLoad() {
if(request.readyState !== 4) {
return;
}
if(request.status === 0) {
// 網絡錯誤和超時錯誤時 status爲 0
return;
}
const responseHeaders = request.getAllResponseHeaders();
const responseDate = responseType !== 'text' ? request.response : request.responseText;
const response:AxiosPromise = {
data:responseDate,
status:request.status,
statusText: request.statusText,
headers: parseHeaders(responseHeaders),
config,
request,
}
handleResponse(response);
}
request.open(method.toUpperCase(),url,true);
// 錯誤開始
// 請求錯誤
request.onerror = function handleError() {
reject(createError('Network Error',config,null,request));
}
// 超時錯誤
request.ontimeout = function handleTimeout() {
reject(createError(`Timeout of ${timeout} ms exceeded`,config,'ECONNABORTED',request));
}
// 錯誤結束
Object.keys(headers).forEach((name) => {
if(data === null && name.toLocaleLowerCase() === 'content-type') {
delete headers[name];
}
request.setRequestHeader(name,headers[name]);
})
request.send(data);
function handleResponse(response: AxiosResponse) : void{
if(response.status >= 200 && response.status < 300) {
reslove(response);
} else {
reject(createError(`Request failed with status code ${response.status}`,config,null,request,response));
}
}
})
}
現在就沒有了,就到這裏,之後會就是用這個 axios 方法來擴展一些方法,例如 axios.get
等。