前后端数据交互(四)——fetch 请求详解
fetch 是 XMLHttpRequest 的升级版,使用js脚本发出网络请求,但是与 XMLHttpRequest 不同的是,fetch 方式使用 Promise,相比 XMLHttpRequest 更加简洁。所以我们告别XMLHttpRequest,引入 fetch 如何使用?
一、fetch介绍
fetch() 是一个全局方法,提供一种简单,合理的方式跨网络获取资源。它的请求是基于 Promise 的,需要详细学习 Promise ,请点击《 Promise详解 》。它是专门为了取代传统的 xhr 而生的。
1.1、fetch使用语法
fetch(url,options).then((response)=>{
//处理http响应
},(error)=>{
//处理错误
})
url :是发送网络请求的地址。
options:发送请求参数,
- body - http请求参数
- mode - 指定请求模式。默认值为cros:允许跨域;same-origin:只允许同源请求;no-cros:只限于get、post和head,并且只能使用有限的几个简单标头。
- cache - 用户指定缓存。
- method - 请求方法,默认GET
- signal - 用于取消 fetch
- headers - http请求头设置
- keepalive - 用于页面卸载时,告诉浏览器在后台保持连接,继续发送数据。
- credentials - cookie设置,默认omit,忽略不带cookie,same-origin同源请求带cookie,inclue无论跨域还是同源都会带cookie。
1.2、response 对象
fetch 请求成功后,响应 response 对象如图:
- status - http状态码,范围在100-599之间
- statusText - 服务器返回状态文字描述
- ok - 返回布尔值,如果状态码2开头的,则true,反之false
- headers - 响应头
- body - 响应体。响应体内的数据,根据类型各自处理。
- type - 返回请求类型。
- redirected - 返回布尔值,表示是否发生过跳转。
1.3、读取内容方法
response 对象根据服务器返回的不同类型数据,提供了不同的读取方法。分别有:
- response.text() -- 得到文本字符串
- response.json() - 得到 json 对象
- response.blob() - 得到二进制 blob 对象
- response.formData() - 得到 fromData 表单对象
- response.arrayBuffer() - 得到二进制 arrayBuffer 对象
上述 5 个方法,返回的都是 promise 对象,必须等到异步操作结束,才能得到服务器返回的完整数据。
1.4、response.clone()
stream 对象只能读取一次,读取完就没了,这意味着,上边的五种读取方法,只能使用一个,否则会报错。
因此 response 对象提供了 clone() 方法,创建 respons 对象副本,实现多次读取。如下:将一张图片,读取两次:
const response1 = await fetch('flowers.jpg');
const response2 = response1.clone();
const myBlob1 = await response1.blob();
const myBlob2 = await response2.blob();
image1.src = URL.createObjectURL(myBlob1);
image2.src = URL.createObjectURL(myBlob2);
1.5、response.body()
body 属性返回一个 ReadableStream 对象,供用户操作,可以用来分块读取内容,显示下载的进度就是其中一种应用。
const response = await fetch('flower.jpg');
const reader = response.body.getReader();
while(true) {
const {done, value} = await reader.read();
if (done) {
break;
}
console.log(`Received ${value.length} bytes`)
}
response.body.getReader() 返回一个遍历器,这个遍历器 read() 方法每次都会返回一个对象,表示本次读取的内容块。
二、请求时 POST 和 GET 分别处理
请求方式不同,传值方式也不同。xhr 会分别处理 get 和 post 数据传输,还有请求头设置,同样 fetch 也需要分别处理。
2.1、get 方式
只需要在url中加入传输数据,options中加入请求方式。如下面代码所示:
<input type="text" id="user"><br>
<input type="password" id="pas"><br>
<button onclick="login()">提交</button>
<script>
function login(){
fetch(`http://localhost:80/fetch.html?user=${user.value}&pas=${pas.value}`,{
method:'GET'
}).then(response=>{
console.log('响应',response)
})
}
</script>
2.2、post 方式
使用 post 发送请求时,需要设置请求头、请求数据等。
将上个实例,改写成 post 方式提交数据,代码如下:
fetch(`http://localhost:80/ES6练习题/53fetch.html`,{
method:'POST',
headers:{
'Content-Type':'application/x-www-form-urlencoded;charset=UTF-8'
},
body:`user=${user.value}&pas=${pas.value}`
}).then(response=>{
console.log('响应',response)
})
如果是提交json数据时,需要把json转换成字符串。如
body:JSON.stringify(json)
如果提交的是表单数据,使用 formData转化下,如:
body:new FormData(form)
上传文件,可以包含在整个表单里一起提交,如:
const input = document.querySelector('input[type="file"]');
const data = new FormData();
data.append('file', input.files[0]);
data.append('user', 'foo');
fetch('/avatars', {
method: 'POST',
body: data
});
上传二进制数据,将 bolb 或 arrayBuffer 数据放到body属性里,如:
let blob = await new Promise(resolve =>
canvasElem.toBlob(resolve, 'image/png')
); let response = await fetch('/article/fetch/post/image', {
method: 'POST',
body: blob
});
三、fetch 常见坑
3.1、fetch兼容性
fetch原生支持率如图:
fetch 是相对较新的技术,IE浏览器不支持,还有其他低版本浏览器也不支持,因此如果使用fetch时,需要考虑浏览器兼容问题。
解决办法:引入 polyfill 完美支持 IE8 以上。
- 由于 IE8 是 ES3,需要引入 ES5 的 polyfill: es5-shim, es5-sham
- 引入 Promise 的 polyfill:es6-promise
- 引入 fetch 探测库:fetch-detector
- 引入 fetch 的 polyfill: fetch-ie8
- 可选:如果你还使用了 jsonp,引入 fetch-jsonp
- 可选:开启 Babel 的 runtime 模式,现在就使用 async/await
polyfill 的原理就是探测fetch是否支持,如果不支持则用 xhr 实现。支持 fetch 的浏览器,响应中文会乱码,所以使用 fetch-detector 和 fetch-ie8 解决乱码问题。
3.2、fetch默认不带cookie
传递cookie时,必须在header参数内加上 credentials:'include',才会像 xhr 将当前cookie 带有请求中。
3.3、异常处理
fetch 不同于 xhr ,xhr 自带取消、错误等方法,所以服务器返回 4xx 或 5xx 时,是不会抛出错误的,需要手动处理,通过 response 中的 status 字段来判断。
前后端数据交互(四)——fetch 请求详解的更多相关文章
- 前后端数据交互(八)——请求方法 GET 和 POST 区别
WEB 开发同学一看 get 和 post 请求方法的区别,第一感觉都是 So easy! 学习ajax.fetch.axios时,发送网络请求携带参数时,都需要分别处理get和post的参数.所以我 ...
- 对GraphQL-BFF:微服务背景下的前后端数据交互方案的研究-------引用
随着多终端.多平台.多业务形态.多技术选型等各方面的发展,前后端的数据交互,日益复杂. 同一份数据,可能以多种不同的形态和结构,在多种场景下被消费. 在理想情况下,这些复杂性可以全部由后端承担.前端只 ...
- 两种方法实现asp.net方案的前后端数据交互(aspx文件、html+ashx+ajax)
一个HTML页面只能显示HTML代码信息,不能与数据库进行数据的交互.asp.net方案提供了网页与数据库交互的方法,这里举出两种:①aspx文件 ②ashx文件+ajax技术 一.创建数据库 这里以 ...
- vue-resource的使用,前后端数据交互
vue-resource的使用,前后端数据交互 1:导入vue与vue-resource的js js下载: https://pan.baidu.com/s/1fs5QaNwcl2AMEyp_kUg ...
- web前后端数据交互
前后端数据交互是每一名web程序员必须熟悉的过程,前后端的数据交互重点在于前端是如何获取后端返回的数据,毕竟后端一般情况下只需要将数据封装到一个jsonMap,然后return就完了.下面通过一个li ...
- 前后端数据交互处理基于原生JS模板引擎开发
json数据错误处理,把json文件数据复制到----> https://www.bejson.com/ 在线解析json 这样能直观的了解到是否是json数据写错,在控制台打断点,那里错误打那 ...
- 前后端数据交互利器--Protobuf
Protobuf 介绍 Protocol Buffers(又名 protobuf)是 Google 的语言中立.平台中立.可扩展的结构化数据序列化机制. https://github.com/prot ...
- 前后端分离,简单JWT登录详解
前后端分离,简单JWT登录详解 目录 前后端分离,简单JWT登录详解 JWT登录流程 1. 用户认证处理 2. 前端登录 3. 前端请求处理 4. 后端请求处理 5. 前端页面跳转处理 6. 退出登录 ...
- 前后端数据交互(六)——ajax 、fetch 和 axios 优缺点及比较
一.ajax.fetch 和 axios 简介 1.1.ajax ajax是最早出现发送后端请求的技术,属于原生 js .ajax使用源码,请点击<原生 ajax 请求详解>查看.一般使用 ...
随机推荐
- python3实现名片管理系统(文件版)
def menu(): #首先定义功能列表函数menu() print(" 名片管理系统 V1.0 ") print("1:增加新用户") print(&quo ...
- PHP:字符串转数组,数组转字符串;字符串截取、替换、查找
字符串转数组$str = 'one|two|three|four'; print_r(explode('|', $str)); //explode 以字符串分割字符串到数组 $str = 'one t ...
- Ming Yin(@kalasoo)在知乎的几个回答 : 观点犀利
这篇文章汇总了掘金前站长Ming Yin(阴明)在知乎的几个犀利的观点,原文可访问zhihu.com/kalasoo 由@flightmakers转载(收藏)在此 你是否有个人网站.可否和大家分享一下 ...
- Java 在Word中创建多级项目符号列表和编号列表
本文分享通过Java程序代码在Word中创建多级项目符号列表和编号列表的方法.程序运行环境如下: IntelliJ IDEA 2018(JDK 1.8.0) Word 2013 Word Jar包:F ...
- Salesforce Integration 概览(六) UI Update Based on Data Changes(UI自动更新基于数据变更)
Salesforce用户界面必须由于Salesforce数据的更改而自动更新.这个场景其实在我所经历的项目中用到的不是特别多,因为客户可能直接点击刷新按钮就直接看到了最新的数据,而不是那种一直不刷新然 ...
- C++实现链表的相关基础操作
链表的相关基础操作 # include <iostream> using namespace std; typedef struct LNode { int data; //结点的数据域 ...
- tkinter 基础教程
目录 介绍 模块 导入方式 API 使用 主窗口 运行窗口 组件列表介绍 Label 标签 Button 按钮 Options 属性选项 文本框 Entry 单行文本框 Text 多行文本框 文本框属 ...
- Redis实战-详细配置-优雅的使用Redis注解/RedisTemplate
1. 简介 当我们对redis的基本知识有一定的了解后,我们再通过实战的角度学习一下在SpringBoot环境下,如何优雅的使用redis. 我们通过使用SpringBoot内置的Redis注解(文章 ...
- HCNA Routing&Switching之DHCP服务
前文我们了解了STP的端口状态.计时器以及端口状态切换和网络拓扑变化相关话题,回顾请参考https://www.cnblogs.com/qiuhom-1874/p/15140672.html:今天我们 ...
- 如何远程调试自定义开发的Flume应用
一.前言 Flume作为当下最流行的大数据采集组件之一.其本身拥有分布式/高可靠/高可用等优点,但相比较于Flink/Spark/Kafka等大数据组件,其对于本地调试的功能支持度并不高,如果我们没有 ...