聊聊fetch
fetch的使用
fetch是一个发起异步请求的新api, 在浏览器(有些不支持)中可以直接使用。
Promise fetch(url, init)
fetch接收两个参数,第一个参数是请求路径,第二个参数是可选的。
fetch函数返回的是一个promise对象。
一个简单使用的例子:
let url = "http://localhost:8080/user/list";
fetch(url)
.then(response => {
// 检查是否正常返回
if(response.status >= 200 && response.status < 300) {
// 返回的是一个promise对象, 值就是后端返回的数据, 调用then()可以接收
return response.json();
}
const err = new Error(response.statusText);
err.response = response;
throw err;
})
.then(data => {
// 后端返回的JSON数据
console.log(data)
})
.catch(err => console.log(err));
因为fetch返回的是一个promise对象, 因此可以链式调用then、catch等函数。
第一次调用then()拿到的只是一个Response对象,这个对象里面有一系列属性,以及方法。
具体可以参考: Response API
这里主要说说status、statusText、ok、body这几个属性
status: 就是服务器返回的状态码(200、400、500)
statusText: 与status对应的文本显示
ok: 一个bool类型的值, 如果成功(状态码是200-299之间)返回就是true, 否则就是false
body: 响应的数据, 无法直接读取,需要使用response.json()、response.text()等方法解析。
通常后端返会的都是JSON数据, 一般使用response.json()即可。response.json()返回的还是一个Promise
对象,接着再调用then()就能获取到后端返回的数据了。
注: 使用fetch发起异步请求时,只有当网络等原因fetch返回的promise才会变成reject状态,而一般的
错误诸如404、500等还是会变成resolve状态, 因此需要再第一个then函数里面检查是否是成功的返回。
可以 检查状态码或者ok属性是否为true。
fetch的第二个参数init
这个参数是可选的, 如果不传这个参数,那么fetch默认使用get方式发起异步请求。
init是一个对象,格式可以参考: fetch API 下面主要列举几个常用的属性。
method: 请求方式(get、post、put等)
headers: 请求头信息
body: 请求参数,对get方式的请求无效,因为get方式请求的参数在url上 。body的格式与headers设置的
Content-Type参数对应。如Content-Type=application/json,那么body是一个JSON格式。
如Content-Type=application/x-www-form-urlencoded(表单默认的形式就是这个),那么body就是一个键值
对形式,诸如: username=wangtao&password=123456这样。
Content-Type可以不设置,会根据body格式自动设置Content-Type的值
mode: 请求的模式,与跨域有关系。有cors、no-cors、same-origin 3个值
cors即使用跨域资源共享这种方式实现跨域,需要服务端支持。这种方式不支持Content-Type=application/json
no-cors也是可以跨域的,但是拿不到返回的值。
same-origin不支持跨域。
与generator函数结合
在redux-saga中使用往往都是通过使用generator函数结合实现异步调用。
function request(url) {
return fetch(url)
.then(response => {
if(response.ok) {
return response.json();
}
const err = new Error(response.statusText);
err.response = response;
throw err;
})
.then(result => ({result}))
.catch(err => ({err}));
}
// 非常像resux-saga处理异步请求的写法
function* asyncFetch() {
const {result, err} = yield request("http://127.0.0.1/user/list")
if(result) {
// 执行逻辑, 展示数据
console.log(result)
} else if(err) {
//处理错误
}
}
//调用asyncFetch(redux-saga自己调用, 不用手写)
const g = asyncFetch();
let next = g.next();
if(!next.done) {
next.value.then(data => {
g.next(data)
})
}
上述代码主要用来理解redux-saga处理异步请求的写法,只是一个雏形。
总结
使用fetch需要注意的几个点
服务端返回错误的状态码,fetch返回的promise也是resolve的,因此需要加判断。
如果请求方式是get,fetch的第二参数的body属性无效。
如果跨域需要指定第二个参数的mode=cors,需要后端支持(Access-Control-Allow-Origin = "*")
此种方式不支持Content-Type=application/json。
聊聊fetch的更多相关文章
- Angular.js!(附:聊聊非原生框架项目)
最近,为了项目接触了一个很火的前端框架Angular.js,下面就Angular做一个简介吧(大牛请绕步,只针对没有接触过angular的人). Angular.js是一款精简的前端框架,如果要追溯它 ...
- 简单聊聊WebSocket
一.概述 上一篇文章<浅析一次HTTP请求>我们分析了简单的一次 HTTP 请求具体是怎么样完成的,分析了 HTTP 协议的数据结构,如何连接,如何断开,又是如何多路复用的,那么今天我们来 ...
- [No0000194]聊聊 Chrome DevTools 中你可能不知道的调试技巧
对于前端开发者来说,ChromeDevTools 绝对是不可或缺的调试工具,我们常用的调试方法包含一些console等,而ChromeDevTools 其实很强大,下面来聊聊一些你可能不知道的debu ...
- C# 读写西门子PLC数据,包含S7协议和Fetch/Write协议,s7支持200smart,300PLC,1200PLC,1500PLC
本文将使用一个gitHub开源的组件技术来读写西门子plc数据,使用的是基于以太网的TCP/IP实现,不需要额外的组件,读取操作只要放到后台线程就不会卡死线程,本组件支持超级方便的高性能读写操作 官方 ...
- python 读写西门子PLC 包含S7协议和Fetch/Write协议,s7支持200smart,300PLC,1200PLC,1500PLC
本文将使用一个gitHub开源的组件技术来读写西门子plc数据,使用的是基于以太网的TCP/IP实现,不需要额外的组件,读取操作只要放到后台线程就不会卡死线程,本组件支持超级方便的高性能读写操作 nu ...
- java android 读写西门子PLC数据,包含S7协议和Fetch/Write协议,s7支持200smart,300PLC,1200PLC,1500PLC
本文将使用一个gitHub开源的组件技术来读写西门子plc数据,使用的是基于以太网的TCP/IP实现,不需要额外的组件,读取操作只要放到后台线程就不会卡死线程,本组件支持超级方便的高性能读写操作 gi ...
- 聊聊Unity项目管理的那些事:Git-flow和Unity
0x00 前言 目前所在的团队实行敏捷开发已经有了一段时间了.敏捷开发中重要的一个话题便是如何对项目进行恰当的版本管理.项目从最初使用svn到之后的Git One Track策略再到现在的GitFlo ...
- Mono为何能跨平台?聊聊CIL(MSIL)
前言: 其实小匹夫在U3D的开发中一直对U3D的跨平台能力很好奇.到底是什么原理使得U3D可以跨平台呢?后来发现了Mono的作用,并进一步了解到了CIL的存在.所以,作为一个对Unity3D跨平台能力 ...
- fir.im Weekly - 聊聊 Google 开发者大会
中国互联网的三大错觉:索尼倒闭,诺基亚崛起,谷歌重返中国.12月8日,2016 Google 开发者大会正式发布了Google Developers 中国网站 ,包含了Android Develope ...
随机推荐
- 异步请求Ajax(取得json数据)
异步请求Ajax 没有学习Ajax之前请求数据的时候都是整个页面全部刷新了一次,也就是每次请求都会重新请求所有的资源.但是在很多时候不需要页面全部刷新,仅仅是需要页面的局部数据刷新即可,此时需要发送异 ...
- 阿里云服务器 CentOS 安装Mysql 5.6
下载:https://dev.mysql.com/downloads/file/?id=471181 第一步: 安装mysql5姿势是要先安装带有可用的mysql5系列社区版资源的rpm包 [ro ...
- js代码技巧
1.js 中不常用的处理方法 //取整 parseInt(a,10); //Before Math.floor(a); //Before a>>0; //Before ~~a; //Aft ...
- vue 未完待续
1. v-text:主要用来更新textContent,可以等同于JS的text属性. <span v-text="msg"></span> 这两者等价: ...
- MFC笔记8
1.在循环使用数组时需要清理数组 CString str; memset(str,0,strlen(str)); 判断两个字符串包含数字大小是否相等 CString str="22" ...
- Object.assign()解释整理
链接:https://blog.csdn.net/wang252949/article/details/79106160 语法 Object.assign(target, ...sources) 参数 ...
- SpringCloud-day02-服务消费者项目建立
4.4microservice-ticket-consumer-80服务消费者项目建立 我们新建一个服务器提供者module子模块,类似前面建的common公共模块,名称是 microservice- ...
- javaMail实现收发邮件(一)
电子邮件的传输过程 电子邮件系统采用客户/服务器模式.电子邮件传送需要用到以下3个重要模块:MUA(Mail User Agent,邮件用户代理):用户通过它与电子邮件服务器打交道.MUA实际上就是邮 ...
- json11阅读
概要:json11是一个基于c++11的json解析库,dropbox出品. 使用 直接举自带单元测试test.cpp中的例子: const string simple_test = R"( ...
- 【Unity】打包安卓APK常见问题
问题:unity error invalid command android 原因:Android版本较新,Unity版本太旧(如4.X),Unity打包APK时调用Android工具使用的命令已被安 ...