你不需要jQuery(三) 新AJAX方法fetch()


Posted in Javascript onJune 14, 2016

XMLHttpRequest来完成ajax有些老而过时了。

fetch()能让我们完成类似 XMLHttpRequest (XHR) 提供的ajax功能。它们之间的主要区别是,Fetch API 使用了 Promises,它让接口更简单、简洁,避免了回调的复杂性,省去了使用复杂的 XMLHttpRequest API。

如果你之前未使用过Promises,你应该先看看《JavaScript Promises 用法》这篇文章。

一、基本Fetch用法

让我们先用一个例子来比较一下使用 XMLHttpRequest 和使用 fetch 之间的不同。我们要请求一个URL,获取JSON格式的返回结果。

XMLHttpRequest
一个 XMLHttpRequest 请求需要两个监听器来捕捉 success 和 error 两种情形,而且需要调用 open() 和 send() 方法。

function reqListener() { 
 var data = JSON.parse(this.responseText); 
 console.log(data); 
}

function reqError(err) { 
 console.log('Fetch Error :-S', err); 
}

var oReq = new XMLHttpRequest(); 
oReq.onload = reqListener; 
oReq.onerror = reqError; 
oReq.open('get', './api/some.json', true); 
oReq.send();

Fetch
我们的 fetch 请求的代码基本上是这样的:

fetch('./api/some.json') 
 .then( 
 function(response) { 
  if (response.status !== 200) { 
  console.log('Looks like there was a problem. Status Code: ' + 
   response.status); 
  return; 
  }

  // Examine the text in the response 
  response.json().then(function(data) { 
  console.log(data); 
  }); 
 } 
 ) 
 .catch(function(err) { 
 console.log('Fetch Error :-S', err); 
 });

我们首先检查请求响应的状态是否是 200,然后才按照 JSON 对象分析响应数据。

fetch()请求获取的内容是一个 Stream 对象。也就是说,当我们调用 json() 方法时,返回的仍是一个 Promise 对象,这是因为对 stream 的读取也是异步的。

返回数据对象的元数据(Metadata)

在上面的例子中,我看到了服务器响应对象Response的基本状态,以及如何转换成JSON。返回的相应对象Response里还有很多的元数据信息,下面是一些:

fetch('users.json').then(function(response) { 
 console.log(response.headers.get('Content-Type')); 
 console.log(response.headers.get('Date'));

 console.log(response.status); 
 console.log(response.statusText); 
 console.log(response.type); 
 console.log(response.url); 
});

响应的对象Response类型

当我们执行一个fetch请求时,响应的数据的类型response.type可以是“basic”, “cors” 或 “opaque”。这些类型用来说明应该如何对待这些数据和数据的来源。

当请求发起自同一个域时,响应的类型将会是“basic”,这时,对响应内容的使用将没有任何限制。

如果请求来自另外某个域,而且响应的具有CORs头信息,那么,响应的类型将是“cors”。 “cors” 和 “basic” 类型的响应基本是一样的,区别在于,“cors”类型的响应限制你只能看到的头信息包括`Cache-Control`, `Content-Language`, `Content-Type`, `Expires`, `Last-Modified`, 和 `Pragma`。

“opaque”类型的响应说明请求来自另外一个域,并且不具有 CORS 头信息。一个opaque类型的响应将无法被读取,而且不能读取到请求的状态,无法看到请求的成功与否。当前的 fetch() 实现无法执行这样的请求。

你可以给fetch请求指定一个模式,要求它只执行规定模式的请求。这个模式可以分为:

“same-origin” 只有来自同域的请求才能成功,其它的均将被拒绝。
“cors” 允许不同域的请求,但要求有正确的 CORs 头信息。
“cors-with-forced-preflight” 在执行真正的调用前先执行preflight check。
“no-cors” 目前这种模式是无法执行的。
定义模式的方法是,使用一个参数对象当做fetch方法的第二个参数:

fetch('http://some-site.com/cors-enabled/some.json', {mode: 'cors'}) 
 .then(function(response) { 
 return response.text(); 
 }) 
 .then(function(text) { 
 console.log('Request successful', text); 
 }) 
 .catch(function(error) { 
 log('Request failed', error) 
 });

串联 Promises

Promises最大的一个特征是,你可以串联各种操作。对于fetch来说,我们可以在各个fetch操作里共享一些逻辑操作。

在使用JSON API时,我们需要检查每次请求响应的状态,然后解析成JSON对象。使用promise,我们可以简单的将分析状态和解析JSON的代码放到一个单独函数里,然后当做promise返回,这样就是代码更条理了。

function status(response) { 
 if (response.status >= 200 && response.status < 300) { 
 return Promise.resolve(response) 
 } else { 
 return Promise.reject(new Error(response.statusText)) 
 } 
}

function json(response) { 
 return response.json() 
}

fetch('users.json') 
 .then(status) 
 .then(json) 
 .then(function(data) { 
 console.log('Request succeeded with JSON response', data); 
 }).catch(function(error) { 
 console.log('Request failed', error); 
 });

我们用 status 函数来检查 response.status 并返回 Promise.resolve() 或 Promise.reject() 的结果,这个结果也是一个 Promise。我们的fetch() 调用链条中,首先如果fetch()执行结果是 resolve,那么,接着会调用 json() 方法,这个方法返回的也是一个 Promise,这样我们就得到一个分析后的JSON对象。如果分析失败,将会执行reject函数和catch语句。

你会发现,在fetch请求中,我们可以共享一些业务逻辑,使得代码易于维护,可读性、可测试性更高。

用fetch执行表单数据提交

在WEB应用中,提交表单是非常常见的操作,用fetch来提交表单数据也是非常简洁。

fetch里提供了 method 和 body 参数选项。

fetch(url, { 
 method: 'post', 
 headers: { 
  "Content-type": "application/x-www-form-urlencoded; charset=UTF-8" 
 }, 
 body: 'foo=bar&lorem=ipsum' 
 })
 .then(json) 
 .then(function (data) { 
 console.log('Request succeeded with JSON response', data); 
 }) 
 .catch(function (error) { 
 console.log('Request failed', error); 
 });

在Fetch请求里发送用户身份凭证信息

如果你想在fetch请求里附带cookies之类的凭证信息,可以将 credentials 参数设置成 “include” 值。

fetch(url, { 
 credentials: 'include' 
})

显而易见,fetch API相比起传统的 XMLHttpRequest (XHR) 要简单的多,相比起jQuery里提供ajax API也丝毫不逊色。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
jquery获取焦点和失去焦点事件代码
Apr 21 Javascript
javascript实现仿腾讯游戏选择
May 14 Javascript
window.onload使用指南
Sep 13 Javascript
fastclick插件导致日期(input[type=&quot;date&quot;])控件无法被触发该如何解决
Nov 09 Javascript
Dojo获取下拉框的文本和值实例代码
May 27 Javascript
jQuery插件FusionCharts绘制的3D双柱状图效果示例【附demo源码】
Apr 20 jQuery
基于Vue单文件组件详解
Sep 15 Javascript
vue中,在本地缓存中读写数据的方法
Sep 21 Javascript
JS页面获取 session 值,作用域和闭包学习笔记
Oct 16 Javascript
vue下axios拦截器token刷新机制的实例代码
Jan 17 Javascript
详解JavaScript中new操作符的解析和实现
Sep 04 Javascript
如何在Vue项目中添加接口监听遮罩
Jan 25 Vue.js
深入理解jQuery 事件处理
Jun 14 #Javascript
使用jquery获取url及url参数的简单实例
Jun 14 #Javascript
JS操作JSON方法总结(推荐)
Jun 14 #Javascript
JavaScript Promise 用法
Jun 14 #Javascript
Javascript基础_简单比较undefined和null 值
Jun 14 #Javascript
Javascript缓存API
Jun 14 #Javascript
JS修改地址栏参数实例代码
Jun 14 #Javascript
You might like
PHP 编程请选择正确的文本编辑软件
2006/12/21 PHP
PHP中如何调用webservice的实例参考
2013/04/25 PHP
php获取$_POST同名参数数组的实现介绍
2013/06/30 PHP
php自定义session示例分享
2014/04/22 PHP
php实现自定义中奖项数和概率的抽奖函数示例
2017/05/26 PHP
Jquery 绑定时间实现代码
2011/05/03 Javascript
JS验证日期的格式YYYY-mm-dd 具体实现
2013/06/29 Javascript
深入讲解AngularJS中的自定义指令的使用
2015/06/18 Javascript
JavaScript中split与join函数的进阶使用技巧
2016/05/03 Javascript
js微信分享API
2020/10/11 Javascript
JS图片放大效果简单实现代码
2016/09/08 Javascript
JavaScript 判断一个对象{}是否为空对象的简单方法
2016/10/09 Javascript
详解JS中遍历语法的比较
2017/04/07 Javascript
Vue + Vue-router 同名路由切换数据不更新的方法
2017/11/20 Javascript
浅谈Node.js 子进程与应用场景
2018/01/24 Javascript
vue使用exif获取图片旋转,压缩的示例代码
2020/12/11 Vue.js
pygame学习笔记(2):画点的三种方法和动画实例
2015/04/15 Python
Python实现扫描局域网活动ip(扫描在线电脑)
2015/04/28 Python
使用Python操作MySQL的一些基本方法
2015/08/16 Python
Python搭建FTP服务器的方法示例
2018/01/19 Python
Django学习教程之静态文件的调用详解
2018/05/08 Python
PyQt5 加载图片和文本文件的实例
2019/06/14 Python
Python 获取numpy.array索引值的实例
2019/12/06 Python
python每5分钟从kafka中提取数据的例子
2019/12/23 Python
Python 实现训练集、测试集随机划分
2020/01/08 Python
python实现五子棋游戏(pygame版)
2020/01/19 Python
Python读取JSON数据操作实例解析
2020/05/18 Python
SmartBuyGlasses台湾:名牌眼镜,名牌太阳眼镜及隐形眼镜
2017/01/04 全球购物
亚马逊印度站:Amazon.in
2017/10/15 全球购物
工作求职自荐信
2014/06/13 职场文书
医院2014国庆节活动策划方案
2014/09/21 职场文书
文员岗位职责
2015/02/04 职场文书
如何制定一份可行的计划!
2019/06/21 职场文书
MySQL性能压力基准测试工具sysbench的使用简介
2021/04/21 MySQL
Linux安装Docker详细教程
2022/07/07 Servers
win10音频服务未响应怎么解决?win10音频服务未响应未修复的解决方法
2022/08/14 数码科技