ajax fetch api,fetch 简介: 新一代 Ajax API

AJAX半遮半掩的底层API是饱受诟病的一件事情. XMLHttpRequest 并不是专为Ajax而设计的. 虽然各种框架对 XHR 的封装已经足够好用, 但我们可以做得更好。更好用的API是 fetch 。下面简单介绍 window.fetch 方法, 在最新版的 Firefox 和 Chrome 中已经提供支持。

XMLHttpRequest

在我看来 XHR 有点复杂, 我不想解释为什么“XML”是大写,而“Http”是“骆峰式”写法。使用XHR的方式大致如下:

// 获取 XHR 非常混乱!

if (window.XMLHttpRequest) { // Mozilla, Safari, ...

request = new XMLHttpRequest();

} else if (window.ActiveXObject) { // IE

try {

request = new ActiveXObject('Msxml2.XMLHTTP');

}

catch (e) {

try {

request = new ActiveXObject('Microsoft.XMLHTTP');

}

catch (e) {}

}

}

// 打开连接, 发送数据.

request.open('GET', 'https://davidwalsh.name/ajax-endpoint', true);

request.send(null);

复制代码

我们可以看出, XHR 其实是很杂乱的; 当然, 通过 JavaScript 框架可以很方便地使用XHR。

fetch 的基本使用

fetch 是全局量 window 的一个方法, 第一个参数是URL:

// url (必须), options (可选)

fetch('/some/url', {

method: 'get'

}).then(function(response) {

}).catch(function(err) {

// 出错了;等价于 then 的第二个参数,但这样更好用更直观 :(

});

复制代码

// 对响应的简单处理

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) {

// 中途任何地方出错...在此处理 :(

});

复制代码

如果你还不习惯 then 方式的写法,那最好学习一下,因为很快就会全面流行。

自定义请求头信息极大地增强了请求的灵活性。我们可以通过 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 */ });

复制代码

下面介绍 Response 和Request 的使用方法!

Request 简介

Request 对象表示一次 fetch 调用的请求信息。传入 Request 参数来调用 fetch, 可以执行很多自定义请求的高级用法:

method - 支持 GET, POST, PUT, DELETE, HEAD

url - 请求的 URL

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 */ });

复制代码

因为 Request 和 fetch 的签名一致, 所以在 Service Workers 中, 你可能会更喜欢使用 Request 对象。关于 ServiceWorker 的相关博客请等待后续更新!

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);

});

复制代码

当然这很简单 , 只是封装了 JSON.parse(jsonString) 而已, 但 json 方法还是很方便的。

处理基本的Text / HTML响应

JSON 并不总是理想的请求/响应数据格式, 那么我们看看如何处理 HTML或文本结果:

fetch('/next/page')

.then(function(response) {

return response.text();

}).then(function(text) {

// 复制代码如上面的代码所示, 可以在 Promise 链式的 then 方法中, 先返回 text() 结果 ,再获取 text 。

处理Blob结果

如果你想通过 fetch 加载图像或者其他二进制数据, 则会略有不同:

fetch('flowers.jpg')

.then(function(response) {

return response.blob();

})

.then(function(imageBlob) {

document.querySelector('img').src = URL.createObjectURL(imageBlob);

});

复制代码

响应 Body mixin 的 blob() 方法处理响应流(Response stream), 并且将其读完。

另一种常用的 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

})

});

复制代码

非常非常简单, 妈妈再也不用担心我的Ajax!

未完的故事(Unwritten Story)

fetch 是个很实用的API , 当前还不允许取消请求, 这使得很多程序员暂时不会考虑它。

新的 fetch API 比起 XHR 更简单也更智能。毕竟,它就是专为AJAX而设计的, 具有后发优势. 而我已经迫不及待地使用了, 即使现在兼容性还不是那么好!

翻译时间: 2016年5月22日

原文时间: 2016年4月15日

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值