关于Ajax,一个最让人诧异的秘密就是,XMLHttpRequest
的底层API其实并不是为现在普遍流行的做法设计的,它本是用来做其它事情的。虽然XMLHttpRequest
目前为止提供的API还是非常好用的,但其实它可以做的更好。而这更好的API已经诞生了,它就是fetch
方法。下面我们来看看基本的window.fetch
的用法。最新版的火狐浏览器和谷歌浏览器都提供了对这个API的支持。
整体看来,XMLHttpRequest
过于复杂,而且它的名字有些困惑,为什么“XML”全是大写,而”Http”采用驼峰式命名方法?不管怎样,XMLHttpRequest
的用法是这样的:
// Just getting XHR is a mess! 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) {} } } // Open, send. request.open('GET', 'http://www.webhek.com/ajax-endpoint', true); request.send(null);
当然,有很多的JavaScript框架将XMLHttpRequest
封装的非常方便,但其内部都是上面这个简单例子里的乱糟糟写法。
fetch
用法fetch
方法是全局对象window
里提供的,它的第一个参数就是URL地址:
// url (required), options (optional) fetch('/some/url', { method: 'get' }).then(function(response) { }).catch(function(err) { // Error :( });
它很像我们之前介绍的电池状态信息API,这个fetch API使用promises处理结果results/callbacks:
// Simple response handling fetch('/some/url').then(function(response) { }).catch(function(err) { // Error :( });; // Chaining for more "advanced" handling fetch('/some/url').then(function(response) { return //... }).then(function(returnedValue) { // ... }).catch(function(err) { // Error :( });;
如果你以前没有用过then
类似的方法,那就学着使用它吧——很快到处都会出现这种方法。
假如说,你需求发起一个JSON请求 — 返回的数据对象里有一个json
方法,能将原始数据转化成JavaScript对象:
fetch('http://www.webhek.com/demo/arsenal.json').then(function(response) { // Convert to JSON return response.json(); }).then(function(j) { // Yay, `j` is a JavaScript object console.log(j); });
显然,它就是一个简单的JSON.parse(jsonString)
调用,但json
方法做为简写方式还是很方便的。
JSON并不是我们在任何时候都需要的数据格式,下面介绍一下如何处理HTML或文本格式的响应:
fetch('/next/page') .then(function(response) { return response.text(); }).then(function(text) { //非常相似,你可以在Promise的
then
方法提供的response对象上使用text()
。
头信息和元信息(Metadata)
response
对象里还包含了丰富的HTTP头信息和metadata信息,你可以直接用get
方法获取它们:fetch('http://www.webhek.com/demo/arsenal.json').then(function(response) { // Basic response properties, available at any time console.log(response.status) console.log(response.statusText) // Grabbing response headers via `get` console.log(response.headers.get('Content-Type')) console.log(response.headers.get('Date')) })你还可以在调用请求过程中set这些头信息:
// url (required), options (optional) fetch('/some/url', { headers: { 'Accept': 'application/json', 'Content-Type': 'application/json' } });
提交表单信息
Ajax另外一个常用的地方是发送表单数据,下面的这个例子就是如何用
fetch
发送表单数据:fetch('/submit', { method: 'post', body: new FormData(document.getElementById('comment-form')) });如果你发送的数据是JSON格式:
fetch('/submit-json', { method: 'post', body: JSON.stringify({ email: document.getElementById('email') answer: document.getElementById('answer') }) });非常容易,而且看起来也非常顺眼!
其它要说明的
fetch
是一个更好用的API,但它目前还没有提供取消请求的方法,所以,程序员用起来也需要考量一下。这个新
fetch
API相比起XMLHttpRequest
更简单,更易读,是很好的Ajax替代方法;fetch
有很明显的优势,相信很快会流行起来!