Fetch 总结
说明
由于 Fetch API 是基于 Promise 设计,有必要先学习一下 Promise 。旧浏览器不支持 Promise ,需要使用 polyfill es6 - promise
如果不支持 fetch 也没有问题,可以使用第三方的 ployfill 来实现只会 fetch : whatwg - fetch 这个用的人多
发送一个 ajax 请求
XHR 方式
var xhr = new XMLHttpRequest(); xhr.open('GET', url); xhr.responseType = 'json'; xhr.onload = function() { console.log(xhr.response); }; xhr.onerror = function() { console.log("Oops, error"); }; xhr.send();
fetch 方式
fetch(url).then(function(res) { return res.json() }).then(function(data) { console.log(data); }).catch(function(e) { console.error(e) })
fetch GET 请求初步
fetch(url, { method: 'GET' }) .then((res) => { return res.text() }) .then((res) => { console.log(res) })
fetch GET 请求的参数传递
fetch(url + '?a=1&b=2', { // 在URL中写上传递的参数 method: 'GET' }) .then((res) => { return res.text() }) .then((res) => { console.log(res) })
fetch POST 请求初步
fetch(url, { method: 'POST' // 指定是POST请求 }) .then((res)=>{ return res.text() }) .then((res)=>{ console.log(res) })
fetch POST 请求参数的传递
let formData = new FormData() formData.append('foo', 1) formData.append('bar', 2) fetch(url, { method: 'POST', body: formData,// 这里是请求对象 }) .then((res) => { return res.text() }) .then((res) => { console.log(res) })
fetch 设置请求的头信息
在 POST 提交的过程中,一般是表单提交,可是,经过查询,发现默认的提交方式是: Content - Type : text / plain ; charset = UTF - 8 ,这个显然是不合理的
fetch(url, { method: 'POST', headers: new Headers({ 'Content-Type': 'application/x-www-form-urlencoded' // 指定提交方式为表单提交 }), body: new URLSearchParams([["foo", 1],["bar", 2]]).toString() }) .then((res)=>{ return res.text() }) .then((res)=>{ console.log(res) })
fetch 通过接口得到 JSON 数据
fetch( url, { // 在URL中写上传递的参数 method: 'GET', headers: new Headers({ 'Accept': 'application/json' // 通过头指定,获取的数据类型是JSON }) }) .then((res) => { return res.json() // 返回一个Promise,可以解析成JSON }) .then((res) => { console.log(res) // 获取JSON数据 })
fetch 强制带 Cookie
默认情况下, fetch 不会从服务端发送或接收任何 cookies , 如果站点依赖于维护一个用户会话,则导致未经认证的请求 ( 要发送 cookies ,必须发送凭据头 )
fetch(url, { method: 'GET', credentials: 'include' // 强制加入凭据头 })
fetch 简单封装一下
/** * 将对象转成 a=1&b=2的形式 * @param obj 对象 */ function obj2String(obj, arr = [], idx = 0) { for (let item in obj) { arr[idx++] = [item, obj[item]] } return new URLSearchParams(arr).toString() } /** * 真正的请求 * @param url 请求地址 * @param options 请求参数 * @param method 请求方式 */ function commonFetcdh(url, options, method = 'GET') { const searchStr = obj2String(options) let initObj = {} if (method === 'GET') { // 如果是GET请求,拼接url url += '?' + searchStr initObj = { method: method, credentials: 'include' } } else { initObj = { method: method, credentials: 'include', headers: new Headers({ 'Accept': 'application/json', 'Content-Type': 'application/x-www-form-urlencoded' }), body: searchStr } } fetch(url, initObj).then((res) => { return res.json() }).then((res) => { return res }) } /** * GET请求 * @param url 请求地址 * @param options 请求参数 */ function GET(url, options) { return commonFetcdh(url, options, 'GET') } /** * POST请求 * @param url 请求地址 * @param options 请求参数 */ function POST(url, options) { return commonFetcdh(url, options, 'POST') }
GET('https://www.baidu.com/search/error.html', {a:1,b:2}) POST('https://www.baidu.com/search/error.html', {a:1,b:2})
常见问题
1.Fetch 请求默认是不带 cookie 的,需要设置 fetch(url , { credentials : 'include' } )
2. 服务器返回 400 , 500 错误码时并不会 reject ,只有网络错误这些导致请求不能完成时, fetch 才会被 reject
3.Response 返回一个被解析后的 promise 对象和数据,有这些解析方式: arrayBuffer() 、 blob() 、、 json() 、 text() 、 formData()