XHR简介
在XHR诞生前,网页要获取客户端和服务器的任何状态更新,都需要刷新一次,在XHR诞生后就可以完全通过JS代码异步实现这一过程。XHR的诞生也使最初的网页制作转换为开发交互应用,拉开了WEB2.0的序幕。
XHR是一种浏览器API,极大简化了异步通信的过程,开发者并不需要关注底层的实现,因为浏览器会为我们完成这些工作,如连接管理、协议协商、HTTP请求格式化等等。最初版本的XHR能力非常有限,只支持文本传输,处理上传能力也不足,对于跨域请求也不支持。为解决这些问题,W3C于2008年发布了“XMLHttpRequest Level2”草案,新增了如下功能:
- 支持请求超时;
- 支持传输二进制和文本数据;
- 支持重写媒体类型和编码响应;
- 支持监控每个请求的进度事件;
- 支持有效的文件上传;
- 支持安全的跨来源请求。
2011年,W3C将“XMLHttpRequest Level2”规范与最初的“XMLHttpRequest”规范合并,所有XHR2新增的功能也都并入了原来的XHR API中,接口不变,功能增强。
1.XHR简介
XMLHttpRequest 对象提供了对 HTTP 协议的完全的访问,包括做出 POST 和 HEAD 请求以及普通的 GET 请求的能力。XMLHttpRequest 可以同步或异步地返回 Web 服务器的响应,并且能够以文本或者一个 DOM 文档的形式返回内容。XHR接口强制要求每个请求都具备严格的HTTP语义–应用提供数据和URL,浏览器格式化请求并管理每个连接的完整生命周期,所以XHR仅仅允许应用自定义一些HTTP首部,但更多的首部是不能自己设定的,如:
- Accept-Charset, Accept-Encoding, Access-Control-*
- Host, Upgrade, Connection, Referer, Origin
- Cookie, Sec-, Proxy-, 及其他首部
浏览器会拒绝绝对不安全的首部重写,以保证应用不能假扮用户代理、用户或请求来源,如Origin由浏览器自动设置,Access-Control-Allow-Origin由服务器设置,如果接受该请求,不包含该字段即可,浏览器发出的请求将作废。
- CORS请求会省略cookie和HTTP认证等用户凭据;
- 客户端被限制只能发送“简单的跨域请求”,包括只能使用GET POSD HEAD三种方式,只能访问通过XHR发送并读取的HTTP首部。
如果想要启用cookie和HTTP认证,客户端必须在发送请求时通过XHR对象发送额外的属性(withCredentials),而服务器也需要以Access-Control-Allow-Credentials响应,表示允许应用发送隐私数据。同样,如果客户需要写入或读取自定义HTTP标头或想要使用“非简单的方法”的请求,那么它必须首先通过发出一个预备请求,以获取第三方服务器的许可,如下所示:
// Preflight request
OPTIONS /resource.js HTTP/1.1
Host: thirdparty.com
Origin: http://example.com
Access-Control-Request-Method: POST
Access-Control-Request-Headers: My-Custom-Header
... // Preflight response
HTTP/1.1 200 OK
Access-Control-Allow-Origin: http://example.com
Access-Control-Allow-Methods: GET, POST, PUT
Access-Control-Allow-Headers: My-Custom-Header
... (actual HTTP request)
W3C CORS规范定义的什么时候必须使用预备请求,“简单”的请求可以跳过它,但也有各种各样场景需要使用预备请求,这就添加一次往返网络延迟。可喜的是,一旦预备请求完成,它可以由客户端缓存,以避免在后续请求进行相同的验证。
在XHR中,可以通过responseType-设置改变响应类型,如下所示:
- “” 字符串(默认值)
- “arraybuffer” ArrayBuffer
- “blob” Blob
- “document” Document
- “json” JavaScript 对象,解析自服务器传递回来的JSON 字符串。
- “text” 字符串
2.数据传输
2.1.数据请求:
下面是通过XHR获取一张图片,并显示到网页上的示例:
var xhr = new XMLHttpRequest();
xhr.addEventListener("progress", updateProgress, false);
xhr.addEventListener("load", transferComplete, false);
xhr.addEventListener("error", transferFailed, false);
xhr.addEventListener("abort", transferCanceled, false);
xhr.open('GET', '/images/photo.webp');
xhr.responseType = 'blob';
xhr.onload = function() {
if (this.status == 200) {
var img = document.createElement('img');
img.src = window.URL.createObjectURL(this.response);
img.onload = function() {
window.URL.revokeObjectURL(this.src);
}
document.body.appendChild(img);
}
};
xhr.send();
2.2.数据上传
上传相关事件在 XMLHttpRequest.upload 对象上被触发,像下面这样,向服务器发送一个formdata格式数据:
var formData = new FormData();
formData.append('id', 123456);
formData.append('topic', 'performance'); var xhr = new XMLHttpRequest(); xhr.upload.addEventListener("progress", updateProgress);
xhr.upload.addEventListener("load", transferComplete);
xhr.upload.addEventListener("error", transferFailed);
xhr.upload.addEventListener("abort", transferCanceled); xhr.open('POST', '/upload');
xhr.onload = function() { ... };
xhr.send(formData);
2.3.数据分片上传:
var blob = ...; const BYTES_PER_CHUNK = 1024 * 1024;
const SIZE = blob.size; var start = 0;
var end = BYTES_PER_CHUNK; while(start < SIZE) {
var xhr = new XMLHttpRequest();
xhr.open('POST', '/upload');
xhr.onload = function() { ... }; xhr.setRequestHeader('Content-Range', start+'-'+end+'/'+SIZE);
xhr.send(blob.slice(start, end)); start = end;
end = start + BYTES_PER_CHUNK;
}
注意:progress 事件在使用 file: 协议的情况下是无效的。
XHR简介的更多相关文章
- [转]XHR简介
在XHR诞生前,网页要获取客户端和服务器的任何状态更新,都需要刷新一次,在XHR诞生后就可以完全通过JS代码异步实现这一过程.XHR的诞生也使最初的网页制作转换为开发交互应用,拉开了WEB2.0的 ...
- script ajax / XHR / XMLHttpRequest
s 利用XHR 调试发送form data表单数据,F5键刷新form表单URL ,http请求地址,获取token,提交. 如:http://pcp.cns*****.com/spcp-web/vm ...
- python-爬虫技能升级记录
====== python-爬虫技能升级记录 ====== ===== (一)感知爬虫及爬取流程 =====<code>从简单存取一个页面到 爬取到大量的定量数据,对技术要求更高,以百度百 ...
- react学习与简介
简介: React是Facebook开发的一款JS库 React解决了什么问题? 1).首先是以往mvc模式的缺陷,当代码库庞大时,mvc非常的复杂,每添加新的功能,项目的复杂度就几何倍的增长,导致代 ...
- java-JProfiler(一)-安装以及简介
一.下载 下载http://www.ej-technologies.com/download/jprofiler/files 目前网上有9.2版本的使用方式,10.暂时还无法完美使用 可以下载zip包 ...
- 第九节:JWT简介和以JS+WebApi为例基于JWT的安全校验
一. 简介 1. 背景 传统的基于Session的校验存在诸多问题,比如:Session过期.服务器开销过大.不能分布式部署.不适合前后端分离的项目. 传统的基于Token的校验需要存储Key-Val ...
- Python Tornado简介
简介 Tornado 是 FriendFeed 使用的可扩展的非阻塞式 web 服务器及其相关工具的开源版本.这个 Web 框架看起来有些像web.py 或者 Google 的 webapp,不过为了 ...
- web API简介(一):API,Ajax和Fetch
概述 今天逛MDN,无意中看到了web API简介,觉得挺有意思的,就认真读了一下. 下面是我在读的时候对感兴趣的东西的总结,供自己开发时参考,相信对其他人也有用. 什么是API API (Appli ...
- {Django基础七之Ajax} 一 Ajax简介 二 Ajax使用 三 Ajax请求设置csrf_token 四 关于json 五 补充一个SweetAlert插件(了解)
Django基础七之Ajax 本节目录 一 Ajax简介 二 Ajax使用 三 Ajax请求设置csrf_token 四 关于json 五 补充一个SweetAlert插件(了解) 一 Ajax简介 ...
随机推荐
- Codeforces Round #523 (Div. 2) C. Multiplicity
C. Multiplicity 题目链接:https://codeforc.es/contest/1061/problem/C 题意: 给出一串数,问它的“好序列“有多少.好序列的定义是,首先是一个子 ...
- 算法入门及其C++实现
https://github.com/yuwei67/Play-with-Algorithms (nlogn)为最优排序算法 选择排序 整个数组中,先选出最小元素的位置,将该位置与当前的第一位交换:然 ...
- Redis之RDB与AOF
AOF定义:以日志的形式记录每个操作,将Redis执行过的所有指令全部记录下来(读操作不记录),只许追加文件但不可以修改文件,Redis启动时会读取AOF配置文件重构数据 换句话说,就是Redis重启 ...
- 虚拟化技术之KVM
虚拟化技术之KVM 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.什么是虚拟化 其实虚拟化技术已经不是一个新技术了,上个世纪六十年代IBM公司已经在使用,只不过后来(上个世纪八 ...
- shell脚本中判断上一个命令是否执行成功
shell脚本中判断上一个命令是否执行成功 shell中使用符号“$?”来显示上一条命令执行的返回值,如果为0则代表执行成功,其他表示失败.结合if-else语句实现判断上一个命令是否执行成功. 示例 ...
- 8、Python-函数
定义 def printInfo(): print("人生苦短,我用Python") 调用 def printInfo(): print("人生苦短,我用Python&q ...
- Java编程思想 学习笔记0(忽略)
前言 emmm...博客荒废了好久,总是有各种借口拖延,做的许多题都没有总结.买了一本厚厚的java书,所以决定先新开一个专题,逼迫自己坚持更新学习进度吧,同时也巩固一下知识,做个记录,不至于荒废时光 ...
- 解决Sublime Text中文标题出现异常情况
打开首选项-设置-用户 用以下覆盖原来配置,保存之后重新打开编辑器即可 { "dpi_scale": 1.0, "font_face" ...
- IIC AT24C02读写数据的一点小体会
一.写数据 unsigned char I2CWriteByte(unsigned int mem_addr,unsigned char*DDATAp,unsigned int count) { u8 ...
- 15. Spring boot CRUD
一.列表页 templates/emp/list.html 0.侧边栏链接: <li class="nav-item"> <a class="nav-l ...