2-4、获取响应数据
2019-12-05 本文已影响0人
Eileen_1d88
上一节,我们从网络层面上获取到了服务器端的响应,但是从代码层面上来看,没有接收响应数据的代码,那么接下来我们要做的就是这一部分的工作,我们希望得到的结果是:
axios({
method: 'post',
url: '/base/post',
data: {
a: 1,
b: 2
}
}).then((res) => {
console.log(res)
})
我们拿到的res对象,希望里面包括响应数据data,响应头headers,状态码status,状态说明statusText,请求配置对象config,以及请XMLHttpRequest的对象实例request。
- 定义AxiosResponse接口类型
interface AxiosResponse {
status: number,
statusText: string,
config: AxiosRequestConfig,
headers: any,
request: any,
data: any
}
- axios返回一个promise对象,所以这里也定义一个axiosPromise接口类型
// 当axios请求返回一个AxiosPromise,
// 那么resolve中返回的就是AxiosResponse类型的响应数据
interface AxiosPromise extends Promise<AxiosResponse> {}
对于一个ajax请求的respons,我们是可以指定它的响应数据的类型的,通过设置XMLHttpRequest对象的responseType属性,于是我们可以给AxiosRequestConfig增加一个属性responseType
interface AxiosRequestConfig {
url: string,
method?: Method,
headers?: any,
data?: any,
params?: any,
responseType?: XMLHttpRequestResponseType
}
responseType的类型是XMLHttpRequestResponseType类型,它的值可以是""、arraybuffer、blob、document、json、text、ms-stream 。
实现获取响应数据的逻辑
首先我们要在xhr中增加onreadystatechange事件的处理函数,并且让xhr函数返回AxiosPromise类型
import { AxiosRequestConfig, AxiosPromise, AxiosResponse } from "./types";
export default function xhr(config: AxiosRequestConfig): AxiosPromise {
return new Promise((resolve, reject) => {
// method和data可能没有, 所以给出默认值
const { url, method = 'get', data = null, headers, responseType } = config
const request = new XMLHttpRequest()
if (responseType) {
request.responseType = responseType
}
request.open(method.toUpperCase(), url)
request.onreadystatechange = function handleLoad() {
// request.readyState不是4,说明请求还未返回
if (request.readyState !== 4) {
return
}
const responseHeaders = request.getAllResponseHeaders()
const responseData = responseType && responseType !== 'text' ? request.response : request.responseText
const response: AxiosResponse = {
data: responseData,
headers: responseHeaders,
status: request.status,
statusText: request.statusText,
config,
request
}
resolve(response)
}
Object.keys(headers).forEach((name) => {
request.setRequestHeader(name, headers[name])
})
request.send(data)
})
}
src/index.ts
export default function axios(config: AxiosRequestConfig): AxiosPromise {
processConfig(config)
return xhr(config)
}
这样,就实现了axios的promise化
编写demo
axios({
method: 'post',
url: '/api/base/post',
// headers: {
// 'content-type': 'application/json;'
// },
data: {
a: 1,
b: 2
}
}).then((res) => {
console.log(res)
})
axios({
method: 'post',
url: '/api/base/post',
responseType: 'json',
data: {
a: 3,
b: 4
}
}).then((res) => {
console.log(res)
})
运行demo之后,我们发现2个问题,第一是headers是json字符串,第二是第一个请求的data是json字符串。
那么接下来,我们将要对headers进行处理