fetch 了解多少?
fetch 的简单介绍
Fetch 被称为下一代 Ajax 技术,采用 Promise 方式来处理数据。是一种简洁明了的 API,比 XMLHttpRequest 更加简单易用。
页面中需要向服务器请求数据时,基本上都会使用 Ajax 来实现。Ajax 的本质是使用 XMLHttpRequest 对象来请求数据,而 XMLHttpRequest 对象是通过事件的模式来实现返回数据的处理。
与 XMLHttpRequest 类似,Fetch 允许你发出 AJAX 请求。区别在于 Fetch API 使用 Promise 方式,Promise 是已经正式发布的 ES6 的内容之一,因此是一种简洁明了的 API,比 XMLHttpRequest 更加简单易用。
XMLHttpRequest 的使用
AJAX 半遮半掩的底层 API 是饱受诟病的一件事情. XMLHttpRequest 并不是专为 Ajax 而设计的。虽然各种框架对 XHR 的封装已经足够好用, 但我们可以做得更好。更好用的 API 是 fetch 。下面简单介绍 window.fetch 方法, 在最新版的 Firefox 和 Chrome 中已经提供支持。
在我看来 XHR 有点复杂。使用 XHR 的方式大致如下:
let getJson = function (url) { return new Promise(function (resolve, reject) { let client = new XMLHttpRequest(); client.open('GET', url); client.setRequestHeader('Accept', 'application/json'); client.responseType = 'json'; client.onreadystatechange = function () { if(this.status === 200) { resolve(this.response) } else { reject(this.statusText) } }; client.send() }) };
fetch 的使用
fetch 是全局量 window 的一个方法, 第一个参数是 URL:
// url (必须), options (可选) fetch('/some/url', { method: 'get' }).then(function(response) { }).catch(function(err) { // 出错了;等价于 then 的第二个参数,但这样更好用更直观 :( });
fetch API 也使用了 JavaScript Promises 来处理结果/回调:
// 对响应的简单处理 fetch('/some/url').then(function(response) { }).catch(function(err) { // 出错了;等价于 then 的第二个参数,但这样更直观 :( }); // 链式处理,将异步变为类似单线程的写法: 高级用法. fetch('/some/url').then(function(response) { return new Promise() //... 执行成功, 第 1 步... }).then(function(returnedValue) { // ... 执行成功, 第 2 步... }).catch(function(err) { // 中途任何地方出错...在此处理 :( });
请求头(Request Headers)
自定义请求头信息极大地增强了请求的灵活性。我们可以通过 new Headers() 来创建请求头:
// 创建一个空的 Headers 对象,注意是 Headers,不是 Header var headers = new Headers(); // 添加(append)请求头信息 headers.append('Content-Type', 'text/plain'); headers.append('X-My-Custom-Header', 'CustomValue'); // 判断(has), 获取(get), 以及修改(set)请求头的值 headers.has('Content-Type'); // true headers.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' });
可以使用的方法包括: append, has, get, set, 以及 delete 。
需要创建一个 Request 对象来包装请求头:
var request = new Request('/some-url', { headers: new Headers({ 'Content-Type': 'text/plain' }) }); fetch(request).then(function() { /* handle response */ });
Request 简介
Request 对象表示一次 fetch 调用的请求信息。传入 Request 参数来调用 fetch, 可以执行很多自定义请求的高级用法:
- method - 支持 GET, POST, PUT, DELETE, HEAD
- url - 请求的 URL
- body(String): HTTP 的请求参数
- headers - 对应的 Headers 对象
- referrer - 请求的 referrer 信息
- mode - 可以设置 cors, no-cors, same-origin
- credentials - 设置 cookies 是否随请求一起发送。可以设置: omit, same-origin
- redirect - follow, error, manual
- integrity - subresource 完整性值(integrity value)
- cache - 设置 cache 模式 (default, reload, no-cache)
Request 的示例如下:
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 */ });
只有第一个参数 URL 是必需的。在 Request 对象创建完成之后, 所有的属性都变为只读属性。
请注意,Request 有一个很重要的 clone 方法, 特别是在 Service Worker API 中使用时 —— 一个 Request 就代表一串流(stream), 如果想要传递给另一个 fetch 方法,则需要进行克隆。
fetch 的方法签名(signature 可理解为配置参数),和 Request 很像, 示例如下:
fetch('/users.json', { method: 'POST', mode: 'cors', redirect: 'follow', headers: new Headers({ 'Content-Type': 'text/plain' }) }).then(function() { /* handle response */ });
Response 简介
Response 代表响应, fetch 的 then 方法接收一个 Response 实例,当然你也可以手动创建 Response 对象 —— 比如在 service workers 中可能会用到. Response 可以配置的参数包括:
- type - 类型,支持: basic, cors
- url
- useFinalURL - Boolean 值, 代表 url 是否是最终 URL
- status - 状态码 (例如: 200, 404, 等等)
- ok - Boolean 值,代表成功响应(status 值在 200-299 之间)
- statusText - 状态值(例如: OK)
- headers - 与响应相关联的 Headers 对象.
// 在 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); });
Response 提供的方法如下:
- 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).
处理 JSON 响应
假设需要请求 JSON —— 回调结果对象 response 中有一个 json()方法,用来将原始数据转换成 JavaScript 对象:
fetch('https://davidwalsh.name/demo/arsenal.json').then(function(response) { // 转换为 JSON return response.json(); }).then(function(j) { // 现在, `j` 是一个 JavaScript object console.log(j); });
处理基本的 Text / HTML 响应
JSON 并不总是理想的请求/响应数据格式, 那么我们看看如何处理 HTML 或文本结果:
fetch('/next/page') .then(function(response) { return response.text(); }).then(function(text) { // <!DOCTYPE .... console.log(text); });
处理 Blob 结果
如果你想通过 fetch 加载图像或者其他二进制数据, 则会略有不同:
fetch('flowers.jpg') .then(function(response) { return response.blob(); }) .then(function(imageBlob) { document.querySelector('img').src = URL.createObjectURL(imageBlob); });
提交表单数据(Posting Form Data)
另一种常用的 AJAX 调用是提交表单数据 —— 示例代码如下:
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 }) });
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论