使用 Fetch完成AJAX请求
使用 Fetch完成AJAX请求
写在前面
无论用JavaScript发送或获取信息,我们都会用到Ajax。Ajax不需要刷新页面就能发送和获取信息,能使网页实现异步更新。
几年前,初始化Ajax一般使用jQuery的ajax
方法:
$.ajax('some-url', {
success: (data) => { /* do something with the data */ },
error: (err) => { /* do something when an error happens */}
});
也可以不用jQuery,但不得不使用XMLHttpRequest
,然而这是[相当复杂]
幸亏,浏览器现在支持Fetch API,可以无须其他库就能实现Ajax
浏览器支持
fetch是相对较新的技术,当然就会存在浏览器兼容性的问题,当前各个浏览器低版本的情况下都是不被支持的,因此为了在所有主流浏览器中使用fetch 需要考虑 fetch 的 polyfill 了
require('es6-promise').polyfill();
require('isomorphic-fetch');
引入这两个文件,就可以支持主流浏览器了
Fetch获取数据解读
使用Fetch获取数据很容易。只需要Fetch你想获取资源。
假设我们想通过GitHub获取一个仓库,我们可以像下面这样使用:
fetch('https://api.github.com/users/chriscoyier/repos');
Fetch会返回Promise,所以在获取资源后,可以使用.then
方法做你想做的。
fetch('https://api.github.com/users/chriscoyier/repos')
.then(response => {/* do something */})
如果这是你第一次遇见Fetch,也许惊讶于Fetch返回的response
。如果console.log
返回的response
,会得到下列信息:
{
body: ReadableStream
bodyUsed: false
headers: Headers
ok : true
redirected : false
status : 200
statusText : "OK"
type : "cors"
url : "http://some-website.com/some-url"
__proto__ : Response
}
可以看出Fetch返回的响应能告知请求的状态。从上面例子看出请求是成功的(ok
是true
,status
是200),但是我们想获取的仓库名却不在这里。
显然,我们从GitHub请求的资源都存储在body
中,作为一种可读的流。所以需要调用一个恰当方法将可读流转换为我们可以使用的数据。
Github返回的响应是JSON格式的,所以调用response.json
方法来转换数据。
还有其他方法来处理不同类型的响应。如果请求一个XML格式文件,则调用response.text
。如果请求图片,使用response.blob
方法。
所有这些方法(response.json
等等)返回另一个Promise,所以可以调用.then
方法处理我们转换后的数据。
fetch('https://api.github.com/users/chriscoyier/repos')
.then(response => response.json())
.then(data => {
// data就是我们请求的repos
console.log(data)
});
可以看出Fetch获取数据方法简短并且简单。
接下来,让我们看看如何使用Fetch发送数据。
Fetch发送数据解读
使用Fetch发送也很简单,只需要配置三个参数。
fetch('some-url', options);
第一个参数是设置请求方法(如post
、put
或del
),Fetch会自动设置方法为get
。
第二个参数是设置头部。因为一般使用JSON数据格式,所以设置ContentType
为application/json
。
第三个参数是设置包含JSON内容的主体。因为JSON内容是必须的,所以当设置主体时会调用JSON.stringify
。
实践中,post
请求会像下面这样:
let content = {some: 'content'};
// The actual fetch request
fetch('some-url', {
method: 'post',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify(content)
})
// .then()...
API
fetch(url, { // url: 请求地址
method: "GET", // 请求的方法POST/GET等
headers: { // 请求头(可以是Headers对象,也可是JSON对象)
'Content-Type': 'application/json',
'Accept': 'application/json'
},
body: , // 请求发送的数据 blob、BufferSource、FormData、URLSearchParams(get或head方法中不能包含body)
cache: 'default', // 是否缓存这个请求
credentials: 'same-origin', //要不要携带 cookie 默认不携带 omit、same-origin 或者 include
mode: "",
/*
mode,给请求定义一个模式确保请求有效
same-origin:只在请求同域中资源时成功,其他请求将被拒绝(同源策略)
cors : 允许请求同域及返回CORS响应头的域中的资源,通常用作跨域请求来从第三方提供的API获取数据
cors-with-forced-preflight:在发出实际请求前执行preflight检查
no-cors : 目前不起作用(默认)
*/
}).then(resp => {
/*
Response 实现了 Body, 可以使用 Body 的 属性和方法:
resp.type // 包含Response的类型 (例如, basic, cors).
resp.url // 包含Response的URL.
resp.status // 状态码
resp.ok // 表示 Response 的成功还是失败
resp.headers // 包含此Response所关联的 Headers 对象 可以使用
resp.clone() // 创建一个Response对象的克隆
resp.arrayBuffer() // 返回一个被解析为 ArrayBuffer 格式的promise对象
resp.blob() // 返回一个被解析为 Blob 格式的promise对象
resp.formData() // 返回一个被解析为 FormData 格式的promise对象
resp.json() // 返回一个被解析为 Json 格式的promise对象
resp.text() // 返回一个被解析为 Text 格式的promise对象
*/
if (resp.status === 200) return resp.json();
// 注: 这里的 resp.json() 返回值不是 js对象,通过 then 后才会得到 js 对象
throw New Error('false of json');
}).then(json => {
console.log(json);
}).catch(error => {
consolr.log(error);
})
常用情况
1.请求 json
fetch('http://xxx/xxx.json').then(res => {
return res.json();
}).then(res => {
console.log(res);
})
2. 请求文本
fetch('/xxx/page').then(res => {
return res.text();
}).then(res => {
console.log(res);
})
3. 发送普通json数据
fetch('/xxx', {
method: 'post',
body: JSON.stringify({
username: '',
password: ''
})
});
4. 发送Form表单数据
var form = document.querySelector('form');
fetch('/xxx', {
method: 'post',
body: new FormData(form)
});
5. 获取图片
fetch('/xxx').then(res => {
return res.blob();
}).then(res => {
document.querySelector('img').src = URL.createObjectURL(imageBlob);
})
6. 上传文件
var file = document.querySelector('.file')
var data = new FormData()
data.append('file', file.files[0])
fetch('/xxx', {
method: 'POST',
body: data
})
7. 封装
require('es6-promise').polyfill();
require('isomorphic-fetch');
export default function request(method, url, body) {
method = method.toUpperCase();
if (method === 'GET') {
body = undefined;
} else {
body = body && JSON.stringify(body);
}
return fetch(url, {
method,
headers: {
'Content-Type': 'application/json',
'Accept': 'application/json'
},
body
}).then((res) => {
if (res.status >= 200 && res.status < 300) {
return res;
} else {
return Promise.reject('请求失败!');
}
})
}
export const get = path => request('GET', path);
export const post = (path, body) => request('POST', path, body);
export const put = (path, body) => request('PUT', path, body);
export const del = (path, body) => request('DELETE', path, body);
参考
总结
Fetch是很好的方法,能发送和接收数据。不需要在编写XHR请求或依赖于jQuery。
尽管Fetch很好,但是其错误处理不是很直接。在处理之前,需要让错误信息进入到
catch
方法中。听说有个zlFetch库,改善了Fetch错误处理de问题。
But ! 现在有了Axios了,还跟我扯啥犊子呢!直接一步到位用Axios吧小盆友~
使用 Fetch完成AJAX请求的更多相关文章
- 使用fetch代替ajax请求 post传递方式
let postData = {a:'b'}; fetch('http://data.xxx.com/Admin/Login/login', { method: 'POST', mode: 'cors ...
- react中使用Ajax请求(axios,Fetch)
React本身只关注于界面, 并不包含发送ajax请求的代码,前端应用需要通过ajax请求与后台进行交互(json数据),可以使用集成第三方ajax库(或自己封装) 常用的ajax请求库 jQuery ...
- ajax、fetch、axios — 请求数据
jquery ajax jq 的ajax是对原生XHR的封装,除此以外还增添了对JSONP的支持.用起来非常方便 用法: $.ajax({ url:发送请求的地址, data:数据的拼接,//发送到服 ...
- Fetch和ajax的比较和区别
传统 Ajax 已死,Fetch 永生 Ajax 不会死,传统 Ajax 指的是 XMLHttpRequest(XHR),未来现在已被 Fetch 替代. 最近把阿里一个千万级 PV 的数据产品全 ...
- [Web 前端] 如何在React中做Ajax 请求?
cp from : https://segmentfault.com/a/1190000007564792 如何在React中做Ajax 请求? 首先:React本身没有独有的获取数据的方式.实际上, ...
- 使用 fetch 代替 ajax(在不支持的浏览器上使用 XHR); This kind of functionality was previously achieved using XMLHttpRequest.
原生 JS Ajax,GET和POST 请求实例代码_javascript技巧_脚本之家 https://www.jb51.net/article/86157.htm 更新时间:2016年06月08日 ...
- Vuejs发送Ajax请求
一.概况 ①vuejs中没有内置任何ajax请求方法 ②在vue1.0版本,使用的插件 vue resource 来发送请求,支持promise ③在vue2.0版本,使用社区的一个第三方库 axio ...
- Ajax请求携带Cookie
目录 xhr ajax cookie跨域处理 客户端 服务端 服务端设置跨域的几种方式 方式一 重写addCorsMappings方法 方式二 对单个接口处理 方式三 @CrossOrigin注解 方 ...
- Axios 取消 Ajax 请求
Axios 取消 Ajax 请求 Axios XMLHttpRequest https://caniuse.com/?search=XMLHttpRequest https://developer.m ...
随机推荐
- 机器人自主移动的秘密,从SLAM技术说起(一)
博客转载自:https://www.leiphone.com/news/201609/c35bn1M9kgVaCCef.html 雷锋网(公众号:雷锋网)按:本文作者SLAMTEC(思岚科技公号sla ...
- latex公式怎么变成图片格式
由于这几天正在复习高中的数学,想写一些博客记录一下,发现数学公式的输入是一个问题,后来知道了latex,去youtube学习了一点入门教程发现挺简单的,不过有一个问题,latex生成的是pdf格式啊, ...
- 100722E The Bookcase
传送门 题目大意 给你一些书的高度和宽度,有一个一列三行书柜,要求放进去书后,三行书柜的高的和乘以书柜的宽度最小.问这个值最小是多少. 分析 我们可以先将所有书按照高度降序排好,这样对于每一层只要放过 ...
- poj3420 Quad Tiling
传送门 题目大意 问讲一个大小为4*n的棋盘用无数1*2的骨牌不重叠覆盖有多少种方案. 分析 我们考虑可以将长为n的棋盘分为两块,一个大小为n-i,另一个大小为i,而为了避免对于不同的i构造出相同的情 ...
- MyEclipse 基本使用(三)
视频地址如下 https://pan.baidu.com/s/1boxK4LT#list/path=%2F%E5%8A%A8%E5%8A%9B%E8%8A%82%E7%82%B9%E8%A7%86%E ...
- C++: I/O流详解(二)——输入输出格式控制
一.格式控制 ios提供直接设置标志字的控制格式函数 iostream和iomanip库还提供了一批控制符简化I/O格式化操作 状态标志 值 含义 输入/输出 skipws 0X0001 跳过输入中的 ...
- .net core 2.0 jwt身份认证系统
经历了很久,.net core 2.0 终于发布了! 之前一直用的core 1.1,升级了2.0后发现认证的机制(Auth)发生了比较大的变化,在1.1中认证配置是在Configure中完成,而在2. ...
- UIDevice
iOS 的 APP 应用开发的过程中,有时为了 bug 跟踪或者获取用反馈的需要自动收集用户设备.系统信息.应用信息等等,这些信息方便开发者诊断问题,当然这些信息是用户的非隐私信息,是通过开发 api ...
- 智能合约安全事故回顾(3)-DOS漏洞导致的KotET事件
现实世界中的网络都是有带宽限制的,想象一下,一个访问量稳定的网站,突然有人利用某种方式爆发式的将网站的访问量提升,这个时候系统会作何反应?如果系统没有合理的防DOS攻击的方式,这种时候往往会造成服务器 ...
- Python列表删除的三种方法
1.使用del语句删除元素 >>> i1 = ["a",'b','c','d'] >>> del i1[0] >>> prin ...