React ajax 发送请求(六)
React 官网链接:
接着上节 React 代理配置(五)
前言
在实际做React 项目的时候, 前端应用需要通过 ajax 请求与后台进行交互,React本身只关注于界面, 并不包含发送ajax请求的代码,所以一般 React 应用中需要集成第三方ajax库(或自己封装,但是一般还是借助第三方库来封装,没有自己完全去封装的)
ajax 请求库
常见的在React 用的 ajax 请求库有以下两个:
-
jQuery: 比较重,如果需要另外引入不建议使用
-
axios:轻量级, 建议使用
- 封装XmlHttpRequest对象的ajax
- promise风格
- 可以用在浏览器端和node服务器端
-
fetch:原生函数,不再使用XmlHttpRequest对象提交ajax请求,老版本浏览器可能不支持
下面主要介绍一下axios 与 fetch ,jQuery 一般不建议在React项目中使用,所以这里不做阐述
axios
axios 简单来说,就是使用 promise风格 、封装XmlHttpRequest对象的ajax,不仅仅可用在浏览器端也可用于node服务器端
文档:axios github
安装
根据安装工具的不同,可选择任一来进行安装:
// npm 安装
npm install axios
// bower 安装
bower install axios
// yarn 安装
yarn add axios
使用介绍
API 介绍
关于 axios 进行后端请求提供了很多相关的API
// 使用即需先引用
import axios from 'axios'
axios.request(config)
// get 请求
axios.get(url[, config])
// post 请求
axios.post(url[, data[, config]])
// put请求
axios.put(url[, data[, config]])
// delete 请求
axios.delete(url[, config])
// head 请求
axios.head(url[, config])
// options 请求
axios.options(url[, config])
// patch 请求
axios.patch(url[, data[, config]])
说明:
- url:访问请求的url
- config:请求的相关config(如果已经利用get请求,指定了url 与 data,config中无需再次配置)常用可配置字段如下:(详细的请查看文档)
{
// 请求url
url: '/user',
// 请求方法,默认是 get
method: 'get', // default
// url的前缀
baseURL: 'https://some-domain.com/api/',
// 请求超时时间,默认是 0
timeout: 1000,
// 在请求发送之前修改data / headers,仅仅可在 'PUT', 'POST', 'PATCH' and 'DELETE'使用
transformRequest: [function (data, headers) {
return data;
}],
// 在请求响应之前修改data
transformResponse: [function (data) {
return data;
}],
//定制化headers
headers: {'X-Requested-With': 'XMLHttpRequest'},
// 请求参数
params: {
ID: 12345
},
// request boby 里面的 `data` ,仅仅可在 'PUT', 'POST', 'PATCH' and 'DELETE'使用
// 若没有设置`transformRequest` is set, 该字段的类型必须满足下面的要求
// - string, plain object, ArrayBuffer, ArrayBufferView, URLSearchParams
// 浏览器: FormData, File, Blob
// NOde: Stream, Buffer
data: {
firstName: 'Fred'
},
// 上传进度
onUploadProgress: function (progressEvent) {
},
// 下载进度
onDownloadProgress: function (progressEvent) {
},
// http response content 最大字节长度
maxContentLength: 2000,
// http request content 最大字节长度
maxBodyLength: 2000,
// 定义了promise是否处理或者拒绝
validateStatus: function (status) {
return status >= 200 && status < 300; // default
},
// 服务器相应的类型,可选值为 'arraybuffer', 'document', 'json', 'text', 'stream'
// 默认是json,如果是下载文件,可以标注为stream
responseType: 'json', // default
// 响应内容编码格式,默认 utf8
responseEncoding: 'utf8', // default
// 若没有对应token则取消发送请求
cancelToken: new CancelToken(function (cancel) {
}),
}
请求返回的数据格式:
{
// 返回数据,最重要的一个字段
data: {},
// Http 状态码
status: 200,
// 状态码对应的状态文本
statusText: 'OK',
// 服务器响应的header
headers: {},
// request 请求携带的config
config: {},
// 生成该response 的request
request: {}
}
一般在实际使用的时候,会创建一个请求实例,设置好一些默认config,若涉及一些请求需要特殊的config,再调用的时候进行覆盖即可,涉及到的API为:
axios.create([config]) // config 可配置为上述说明一致
example:
const instance = axios.create({
baseURL: 'https://some-domain.com/api/', // 指定路径前缀
timeout: 1000 // 指定超时时间
});
Example
Get 请求,两种方式,一般都会对请求进行封装,常用的是第二种
- 每个请求单独进行,利用 axios.get API进行请求
- 进行封装,利用 axios.create API创建一个实例,然后不同的方法分别进行请求
import axios from "axios";
// 第一种,利用get请求API来进行请求
// 参数可直接在url后面拼接
axios.get('/user?ID=12345' , {
baseURL: 'https://some-domain.com/api/', // 指定路径前缀
timeout: 1000 // 指定超时时间
})
.then(function (response) {
console.log(response.data);
console.log(response.status);
console.log(response.statusText);
console.log(response.headers);
console.log(response.config);
})
.catch(function (error) {
console.log(error);
});
// 第二种,设置实例后来进行请求,实例设置好默认的config
const instance = axios.create({
baseURL: 'https://some-domain.com/api/', // 指定路径前缀
timeout: 1000 // 指定超时时间
});
instance['get']('/user?ID=12345').then(function (response) {
console.log(response.data);
console.log(response.status);
console.log(response.statusText);
console.log(response.headers);
console.log(response.config);
})
.catch(function (error) {
console.log(error);
});
Post请求:
,两种方式,一般都会对请求进行封装,常用的是第二种
- 每个请求单独进行,利用 axios.post API进行请求
- 进行封装,利用 axios.create API创建一个实例,然后不同的方法分别进行请求
// 第一种,利用post请求API来进行请求
// post请求,第一个参数是url,第二个参数是data,data 以对象的方式进行传入
axios.post('/user', {
firstName: 'Fred',
lastName: 'Flintstone'
}, { // 指定header(如果规定要以form-data请求)
baseURL: 'https://some-domain.com/api/', // 指定路径前缀
timeout: 1000, // 指定超时时间
headers: { // 指定header
'Content-Type': 'multipart/form-data'
})
.then(function (response) {
console.log(response.data);
console.log(response.status);
console.log(response.statusText);
console.log(response.headers);
console.log(response.config);
})
.catch(function (error) {
console.log(error);
});
// 第二种,先设置一些请求都默认的config
const instance = axios.create({
baseURL: 'https://some-domain.com/api/', // 指定路径前缀
timeout: 1000 // 指定超时时间
});
instance['post']('/user', {
firstName: 'Fred',
lastName: 'Flintstone'
}, { // 单独再指定header(如果规定要以form-data请求)
headers: { // 指定header
'Content-Type': 'multipart/form-data'
}).then(function (response) {
console.log(response.data);
console.log(response.status);
console.log(response.statusText);
console.log(response.headers);
console.log(response.config);
})
.catch(function (error) {
console.log(error);
});
fetch
fetch ,自带的原生函数,不再使用XmlHttpRequest对象提交ajax请求,其设计符合关注分离(Separation of Concerns)的原则,有的老版本浏览器可能不支持,它也有很多的优点,例如:
- 语法简洁,更加语义化
- 基于标准 Promise 实现,支持 async/await
- 同构方便
文档:
使用介绍
因为 fetch 是原生自带的,所以无需安装,直接使用
API介绍
关于 fetch 相关的API 与 axios 相比就少了很多:
fetch(url [, options])
说明:
url:请求的url
options:可选项,可配置字段如下
{
method: "POST", // 请求方法,默认为GET
body: JSON.stringify(data), // HTTP 请求body
headers: { // headers 定制,默认为{}
"Content-Type": "application/json"
},
credentials: "same-origin" // 认证字段,三种取值,默认是 "omit"
// `"omit"` - 不要在请求中包含身份验证凭据(例如cookie)
// `"same-origin"` - 在对同一站点的请求中包含凭据
// `"include"` - 在对所有站点的请求中包含凭据
}
请求返回的数据介绍:
{
status: 200 , // HTTP 状态码(100–599)
statusText: "ok" // 状态码对应的文本
ok:True, // 如果状态码是 2xx 则为True,布尔值
headers: {} // 响应头
url: "" // 请求url
}
// 关于获取到的数据,有几种方式获取到
text() // 将response 结果 作为 text 接收
json() // 将response 结果 经过 JSON.parse(responseText) 后接收
blob() // 将 response 结果 作为 Blob 接收
arrayBuffer() // 将 response 结果 作为 ArrayBuffer 接收
formData() - // 将 response 结果 作为 FormData 接收 ,可直接作为另外一个请求的formData
Example
注意点:当服务器返回 400,500 错误码时并不会 reject,只有网络错误这些导致请求不能完成时,fetch 才会被 reject,所以下面的代码(大家可以试试),即使是400/500的话,也会走到response那一步,而不是直接走到error(大家可以尝试一下),简单来说,只要服务器响应了,就是response,然后再获取数据
fetch(`/api1/search/users2?q=${keyWord}`).then(
response => {
console.log('联系服务器成功了');
return response.json()
},
error => {
console.log('联系服务器失败了',error);
return new Promise(()=>{})
}
).then(
response => {console.log('获取数据成功了',response);},
error => {console.log('获取数据失败了',error);}
)
GET请求:
fetch(url).then(function(response) {
return response.json()
}).then(function(data) {
console.log(data)
}).catch(function(e) {
console.log(e)
});
// 简化版
const response= await fetch(url)
const data = await response.json()
POST请求:
fetch(url, {
method: "POST",
body: JSON.stringify(data),
headers: {
"Content-Type": "application/json"
},
credentials: "same-origin"
}).then(function(response) {
response.status //=> number 100–599
response.statusText //=> String
response.headers //=> Headers
response.url //=> String
return response.text()
}, function(error) {
error.message //=> String
})
总结
虽然国外很多新的库都默认使用了 Fetch,但是吧,我们平时开发使用较多的还是axios,自己封装一个请求js,根据不同的请求方法进行响应的请求,统一进行请求的默认设置、异常捕获与错误处理