文章来源:https://www.oxxostudio.tw/articles/201908/js-fetch.html
原文作者:oxxostudio
由于网页为繁体内容,术语描述和话术与我们有差异的问题,笔者在保证不改变原意的基础上做了调整,并在此基础上进行了错误校正,如发现问题,欢迎你的指正。
开篇
自从Fetch API 问世以来,我们就能使用漂亮的语法发送HTTP Request 或取后台接口数据,这篇文章将会分享我自己常用的Fetch方法( GET、POST、搭配await 或promise.all...等) ,随着浏览器的普遍支持,也就不太需要使用XMLHttpRequest 或jQuery AJAX,我们的代码看起来也就更加简洁干净啰~
01
Fetch 基本用法
fetch()方法,包含了需要fetch 的网址和对应的属性设定( 例如method、headers、mode、body...等,最基本的写法属性不一定要填),执行之后会送出Request,如果得到回应就会回传带有Response 的Promise 内容,使用then 将回传值传递下去。
fetch('网址')
.then(function(response) {
// 处理 response
}).catch(function(err) {
// 错误处理
});
举例来说,通过天气数据开放平台可以取得许多气象资料(例如阿里云的API开放平台),下面的示例获取北京的当日气温,因为结果返回为json格式,所以在fetch取得数据之后,通过json()的方法处理数据,接着传递到下一层,就能显示出「北京市的当日气温」。
fetch('天气数据开放平台网址')
.then(res => {
return res.json();
}).then(result => {
let city = result.cwbopendata.location[14].parameter[0].parameterValue;
let temp = result.cwbopendata.location[14].weatherElement[3].elementValue.value;
console.log(`${city}的当前气温 ${temp} 摄氏度`); // 得到 北京市的气温 29.30摄氏度
});
02
Fetch 的 Request 属性
以下列出Fetch常用的的Request属性。(更多属性请参考fetch Request )
属性 | 设定值 |
---|---|
url | 第一个参数,必填项,代表需要fetch对象的网址 |
method | GET、POST、PUT、DELETE、HEAD ( 默认GET ) |
headers | 设置相关的Headers 内容( 预设{} ) |
mode | cors、no-cors、same-origin、navigate ( 默认cors ) |
referrer | no-referrer、client 或某个网址( 默认client ) |
credentials | omit、same-origin、include ( 默认omit ) |
redirect | follow、error、manual ( 默认manual ) |
cache | default、no-store、reload、no-cache、force-cache ( 默认default ) |
03
Fetch 的Response 属性
以下列出Fetch常用的Response属性。(更多属性和方法请参考fetch Response )
属性 | 设定值 |
---|---|
headers | 包含与response 相关的Headers 内容 |
ok | 成功返回true,不成功返回alse |
status | 状态代码,成功为200 |
statusText | 状态信息,成功为ok |
type | response 的类型,例如basic、cors...等 |
url | response 的url |
04
Fetch 的Response 方法
以下列出Fetch常用的Response方法。(更多属性和方法请参考fetch Response )。
属性 | 设定值 |
---|---|
json() | 返回Promise,resolves 是JSON 对象 |
text() | 返回Promise,resolves 是text string |
blob() | 返回Promise,resolves 是blob ( 非结构化对象,例如文字或二进制信息) |
arrayBuffer() | 返回Promise,resolves 是ArrayBuffer ( 有多少bytes ) |
formData() | 返回Promise,resolves 是formData ( 表单资料对应的的Key 或Value ) |
clone() | 创建一个Response对象的克隆。 |
error() | 返回Response 的错误内容 |
05
Fetch 的Get 用法
Get 是Fetch 最简单的方法,使用Get 必须要将fetch 第二个参数里的method 设定为get,如果遇到跨域问题,就搭配其他属性例如mode、credentials 来进行细部设定( 但针对非跨域的就没用了),下方的示例我做了一个简单的后端请求,通过fetch 传递姓名和年纪的参数,就会看到后端回应一串文字。
const name = 'oxxo';
const age = 18;
const uri = `https://网址/exec?name=${name}&age=${age}`;
fetch(uri, {method:'GET'})
.then(res => {
return res.text();
// 使用 text() 可以得到纯文字 String
}).then(result => {
console.log(result);
// 得到「你的名字是:oxxo,年紀:18 岁。」
});
06
Fetch 的Post 用法
使用POST方法可以搭配body属性设定传递参数,比如我的接口地址,可以接收name和age所组成的JSON请求,当网址接收到要求后,就会回应一个json对象,需要注意的是,如果是传递「中文」可能会出现乱码,这时可以使用encodeURI来做转码,且要通过JSON.stringify来转换成string方式传递。
const uri = '网址';
fetch(uri, {
method:'POST',
body:encodeURI(JSON.stringify({
name:'oxxo',
age:18
})),
headers: {
'Content-Type': 'application/x-www-form-urlencoded; charset=utf-8'
}
})
.then(res => {
return res.json();
// 使用 json() 可以得到 json 对象
}).then(result => {
console.log(result);
// 得到 {name: "oxxo", age: 18, text: "你的名字是 oxxo,年纪18岁~"}
});
07
Fetch 搭配async、await、promise.all
过去在XMLHttpRequest 或jQuery AJAX 的全盛时期,如果要确保每个GET 或POST 的要求,都要按照指定的顺序进行,往往会用上一连串的callback 辅助,但是当callback 越来越多,代码也就越来越难管理,然而fetch 返回的是一个Promise,我们也就能直接利用await 或promise.all 的作法,轻松掌握同步与非同步之间的转换。
下方的例子是一个非同步的示例,因为没有进行任何的同步处理,所以执行之后,会先出现hello的文字,接着才是通过fetch 得到的结果。
const postURL = (name,age) => {
const uri = 'https://网址;
return fetch(uri, {
method:'POST',
body:encodeURI(JSON.stringify({
name:name,
age:age
})),
headers: {
'Content-Type': 'application/x-www-form-urlencoded; charset=utf-8'
}
})
.then(res => {
return res.json();
}).then(result =>{
console.log(result);
});
};
postURL('oxxo',18);
console.log('hello!!!');
postURL('tom',18);
因为fetch 的特性,可以改成async 和await 的写法,执行后也就能按照我们要的顺序进行。
await Promise.all([postURL('oxxo',18), postURL('tom',18)]);
console.log('hello!!!');
08
兼容性
说了这么多,你一定关心这个API的兼容性,现代浏览器大部分还是支持的,可以放心使用,如下图所示:
Fetch API 的神奇,简化了许多原本较为复杂的用法,也让项目代码写起来更加干净易读好维护。更重要的是 JavaScript ES6 原生支持,你不需要安装任何依赖包,直接可以在项目中使用。