自从Fetch API 问世以来,我们就能使用漂亮的语法发送HTTP Request 或取后台接口数据,这篇文章将会分享我自己常用的Fetch方法( GET、POST、搭配await 或promise.all...等) ,随着浏览器的普遍支持,也就不太需要使用XMLHttpRequest 或jQuery AJAX,我们的代码看起来也就更加简洁干净啰~
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摄氏度 });
以下列出Fetch常用的的Request属性。(更多属性请参考fetch Request )
以下列出Fetch常用的Response属性。(更多属性和方法请参考fetch Response )
以下列出Fetch常用的Response方法。(更多属性和方法请参考fetch Response )
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 岁。」 });
使用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岁~"} });
过去在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 的写法,执行后也就能按照我们要的顺序进行。
async function(){ // 设定为 async 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); }); }; await postURL('oxxo',18); // 使用 await console.log('hello!!!'); await postURL('tom',18); // 使用 await }();
最后那段await 的代码,也可以改成promise.all 的方法,就会先fetch,然后再出现hello的文字,不过也因为promise.all无法保证其载入顺序,就可能会发生tom 在oxxo之前出现的状况呦。
await Promise.all([postURL('oxxo',18), postURL('tom',18)]); console.log('hello!!!');
说了这么多,你一定关心这个API的兼容性,现代浏览器大部分还是支持的,可以放心使用,如下图所示:
文章来源:https://www.oxxostudio.tw/articles/201908/js-fetch.html
原文作者:oxxostudio
由于网页为繁体内容,术语描述和话术与我们有差异的问题,笔者在保证不改变原意的基础上做了调整,并在此基础上进行了错误校正,如发现问题,欢迎你的指正
Fetch API 的神奇,简化了许多原本较为复杂的用法,也让项目代码写起来更加干净易读好维护。
更多参考资源:
MDN:Using Fetch
https://developer.mozilla.org/zh-CN/docs/Web/API/Fetch_API/Using_Fetch
AJAX 与Fetch API
https://eyesofkids.gitbooks.io/JAVAscript-start-from-es6/content/part4/ajax_fetch.html
更多精彩内容,请关注“前端达人”公众号