1. 概览
fetch(url/request[, options]) var request = new Request(url/request[, options]);
fetch 是全局量 window 的一个方法
request 是一个 Request 对象,Request 参数和 fetch 参数相同
options 是一个对象,主要key 如下:
1234567891011 | method: GET/POST等headers: 一个普通对象,或者一个 Headers 对象body: 传递给服务器的数据,可以是字符串/Buffer/Blob/FormData,如果方法是 GET/HEAD,则不能有此参数mode: cors / no-cors / same-origin, 是否跨域,默认是 no-corscredentials: omit / same-origin / includecache: default / no-store / reload / no-cache / force-cache / only-if-cachedredirect: follow / error / manualreferrer: no-referrer / client / 或者一个urlreferrerPolicy: no-referrer / no-referrer-when-downgrade / origin / origin-when-cross-origin / unsafe-urlintegrity: 资源完整性验证fetch() 返回一个 promise,所以这么用 |
fetch API 使用 Promises 来处理结果/回调
123456789101112131415 | fetch('/some/url').then(function(response) {}).catch(function(err) { // 出错了;等价于 then 的第二个参数,但这样更直观 :(});// 链式处理,将异步变为类似单线程的写法: 高级用法.fetch('/some/url').then(function(response) { return //... 执行成功, 第1步...}).then(function(returnedValue) { // ... 执行成功, 第2步...}).catch(function(err) { // 中途任何地方出错...在此处理 :( }); |
2. Headers
1234567891011121314151617181920 | // 创建一个空的 Headers 对象,注意是Headers,不是Headervar headers = new Headers();// 添加(append)请求头信息headers.append('Content-Type', 'text/plain');headers.append('X-My-Custom-Header', 'CustomValue');// 判断(has), 获取(get), 以及修改(set)请求头的值headers.has('Content-Type'); // trueheaders.get('Content-Type'); // "text/plain"headers.set('Content-Type', 'application/json');// 删除某条请求头信息(a header)headers.delete('X-My-Custom-Header');// 创建对象时设置初始化信息var headers = new Headers({ 'Content-Type': 'text/plain', 'X-My-Custom-Header': 'CustomValue'}); |
Headers对象方法:
123456789 | append(key, value)delete(key)entries() 返回一个遍历器,类似二维数组,每一个 key 和它对应的 value 构成一个数组get(key) 获取指定 key 的value,如果key被添加了多次,则返回第一次添加时的 valuegetAll(key) 返回 key 对应的所有 value,组成一个数组has(key)keys() 所有 key 组成的遍历器set(key, value) 更改 key 的值,如果 key 不存在,则相当于 appendvalues() 所有 value 组成的遍历器 |
12345678 | //创建一个 Request 对象来包装请求头(Request Headers)var request = new Request('/some-url', { headers: new Headers({ 'Content-Type': 'text/plain' })});fetch(request).then(function() { /* handle response */ }); |
3. Request
var request = new Request(url/request[, options]);
Request 对象表示一次 fetch 调用的请求信息。
属性(全部只读):
123456789 | method - 支持 GET, POST, PUT, DELETE, HEADurl - 请求的 URLheaders - 对应的 Headers 对象referrer - 请求的 referrer 信息mode - 可以设置 cors, no-cors, same-origincredentials - 设置 cookies 是否随请求一起发送。可以设置: omit, same-originredirect - follow, error, manualintegrity - subresource 完整性值(integrity value)cache - 设置 cache 模式 (default, reload, no-cache) |
示例:
1234567891011 | var request = new Request('/users.json', { method: 'POST', mode: 'cors', redirect: 'follow', headers: new Headers({ 'Content-Type': 'text/plain' })});// 使用!fetch(request).then(function() { /* handle response */ }); |
在 Request 对象创建完成之后, 所有的属性都变为只读属性。一个 Request 就代表一串流(stream), 如果想要传递给另一个 fetch 方法,则需要进行克隆(clone 方法)。
4. Response
var response = new Response([body][, init])
Response 代表响应, fetch 的 then 方法接收一个 Response 实例。
属性:
123456789 | headers //与响应相关联的 Headers 对象ok //Boolean值,代表成功响应。status在 200 和 299 之间为 trueredirected //表示该Response是否来自一个重定向,如果是的话,它的URL列表将会有多个status //状态码 (例如: 200, 404, 等等)statusText //状态值(例如: OK)type //类型 basic / cors / error / opaqueurl //包含这个请求的URLbodyUsed //存储一个Boolean判断主体是否已经被用于一个响应中useFinalURL //Boolean 值, 代表 url 是否是最终 URL |
方法:
12345678 | clone() - 创建一个新的 Response 克隆对象.error() - 返回一个新的,与网络错误相关的 Response 对象.redirect() - 重定向,使用新的 URL 创建新的 response 对象..arrayBuffer() - Returns a promise that resolves with an ArrayBuffer.blob() - 返回一个 promise, resolves 是一个 Blob.formData() - 返回一个 promise, resolves 是一个 FormData 对象.json() - 返回一个 promise, resolves 是一个 JSON 对象.text() - 返回一个 promise, resolves 是一个 USVString (text). |
示例:
12345678910111213 | // 在 service worker 测试中手动创建 response// new Response(BODY, OPTIONS)var response = new Response('.....', { ok: false, status: 404, url: '/'});// fetch 的 `then` 会传入一个 Response 对象fetch('/') .then(function(responseObj) { console.log('status: ', responseObj.status); }); |
5. 处理 JSON响应
封装了 JSON.parse(jsonString)
1234567 | fetch('https://xxx.json').then(function(response) { // 转换为 JSON return response.json();}).then(function(j) { // 现在, `j` 是一个 JavaScript object console.log(j); }); |
6. 处理 Text / HTML响应
1234567 | fetch('/next/page') .then(function(response) { return response.text(); }).then(function(text) { // <!DOCTYPE .... console.log(text); }); |
7. 处理Blob结果
Blob表示二进制原始数据,一个Blob对象就是一个包含有只读原始数据的类文件对象。
创建blob
1. 通过构造函数
1234 | var blob = new Blob(dataArr:Array<any>, opt:{type:string}); //dataArray:数组,包含了要添加到Blob对象中的数据,数据可以是任意多个ArrayBuffer,ArrayBufferView, Blob,或者 DOMString对象。//opt:对象,用于设置Blob对象的属性(如:MIME类型) |
2. 通过Blob.slice()
12345 | Blob.slice(start:number, end:number, contentType:string)\start:开始索引,默认为0\end:截取结束索引(不包括end)\contentType:新Blob的MIME类型,默认为空字符串 |
3. 通过canvas.toBlob()
1234 | var canvas = document.getElementById("canvas");canvas.toBlob(function(blob){ console.log(blob);}); |
应用
https://www.cnblogs.com/hhhyaaon/p/5928152.html
- 通过Blob.slice方法,可以将大文件分片,轮循向后台提交各文件片段,即可实现文件的分片上传。
- window.URL对象可以为Blob对象生成一个网络地址,结合a标签的download属性,可以实现点击url下载文件。
- 把图片转化为Blob对象,生成URL(URL.createObjectURL(blob)),来显示图片。
通过 fetch 加载图像或者其他二进制数据
1234567 | fetch('flowers.jpg') .then(function(response) { return response.blob(); }) .then(function(imageBlob) { document.querySelector('img').src = URL.createObjectURL(imageBlob); }); |
8. 提交表单数据(Posting Form Data)
12345678910111213 | fetch('/submit', { method: 'post', body: new FormData(document.getElementById('comment-form'))});//提交json数据fetch('/submit-json', { method: 'post', body: JSON.stringify({ email: document.getElementById('email').value answer: document.getElementById('answer').value })}); |
9. 跨域
https://www.zhihu.com/question/47029864/answer/150069385
如果服务器支持 CORS, 则在客户端设置相应的 Access-Control-Allow-Origin
即可得到数据。
1234567891011 | let myHeaders = new Headers({ 'Access-Control-Allow-Origin': '*', 'Content-Type': 'text/plain'});fetch(url, { method: 'GET', headers: myHeaders, mode: 'cors'}) .then((res) => { // TODO }) |
10. 在fetch中使用jsonp
JSONP only supports GET method, same as fetch-jsonp.
参考文章
https://segmentfault.com/a/1190000007455901
http://blog.csdn.net/renfufei/article/details/51494396
https://davidwalsh.name/fetch