fetch介绍
ES6内置的API,本身就是基于promise,用全新的方案实现客户端和服务器端的数据请求
-
fetch基础语法:
let promise实例(p) = fetch(请求地址,配置项)
-
当请求成功,p的状态是fulfilled,值是请求回来的内容;如果请求失败,p的状态是rejected,值是失败原因!
-
fetch和axios有一个不一样的地方:
- 在fetch中,只要服务器有反馈信息(不论HTTP状态码是多少),都说明网络请求成功,最后的实例p都是fulfilled,只有服务器没有任何反馈(例如:请求中断、请求超时、断网等),实例p才是rejected!
- 在axios中,只有返回的状态码是以2开始的,才会让实例是成功态!
配置项
- method 请求的方式,默认是GET「GET、HEAD、DELETE、OPTIONS;POST、PUT、PATCH」
- cache 缓存模式「*default, no-cache, reload, force-cache, only-if-cached」
- credentials 资源凭证(例如cookie)「include, *same-origin, omit」(在客户端和服务器通信中,只要客户端设置了cookie,在每一次请求的时候,默认就会在请求头中,基于cookie字段,把本地设置的cookie信息,传递给服务器。)
fetch默认情况下,跨域请求中,是不允许携带资源凭证的,只有同源下才允许
include:同源和跨域下都可以
same-origin:只有同源才可以
omit:都不可以 - headers:普通对象{}/Headers实例
自定义请求头信息 - body:设置请求主体信息
只适用于POST系列请求,在GET系列请求中设置body会报错{让返回的实例变为失败态}- JSON字符串 application/json
{"name":"xxx","age":14,...}
- URLENCODED字符串 application/x-www-form-urlencoded
xxx=xxx&xxx=xx
- 普通字符串 text/plain
- FormData对象 multipart/form-data, 主要运用在文件上传(或者表单提交)的操作中
let fm=new FormData(); fm.append('file',文件); ...
- 二进制或者Buffer等格式
- …
- JSON字符串 application/json
- 我们发现,相比较于axios来讲,fetch没有对GET系列请求问号传参的信息做特殊的处理(axios中基于params设置问号参数信息),需要自己手动拼接到URL的末尾才可以
fetch的二次封装实现流程
通过上面介绍我们可以实现feach请求的封装实现
借鉴axios可以封装如下:
- 首先接收参数
myFethod接收参数是个对象
参数有url地址,method请求方式,params请求参数,data请求体
function myFetch(fetchData){
let {url, method, params, query} = fetchData
method = method.toUpperCase()
}
- 处理请求数据
用于请求参数或数据拼接
// 解析query数据
function queryParse(query){
let queryText = "";
for(let key in query){
queryText += `${key}=${query[key]}&`;
}
return queryText.slice(0,-1);
}
// 解析params数据
function paramsParse(params){
let paramsText = ""
for (let key in params) {
paramsText += `${key}=${params[key]}&`
}
return paramsText.length > 0 ? "?" + paramsText : paramsText
}
- 处理完数据判断请求方式发起请求
根据不同请求方式发生不同请求
这里实例get和post请求
if(method === "POST"){
return fetch(url,{
method,
body: queryParse(query),
mode: 'cors',
cache: 'default'
}).then(res => {
return res.json()
})
}
if(method === "GEt"){
if(params.length > 1){
return fetch(url + paramsParse(params),{
method,
mode: 'cors',
cache: 'default'
}).then(res => {
return res.json()
})
}
return fetch(url + paramsParse(params),{
method,
mode: 'cors',
cache: 'default'
}).then(res => {
return res.json()
})
}
- 使用方法如下:
let res = myFetch({
url: '/api/shoplist',
method: "get",
params: {
page: 1
}
})
以上就是fetch请求的二次封装
res接收的是服务器响应数据(异步请求)
封装方法时注意点
注意区分method请求方式,我这里使用的toUpperCase()转换大写
get请求和post请求请求参数不同,get请求参数是拼接到url上的,post请求是挂载到body上的,body需要是一个字符串类似于get请求参数拼接的方式