[转]XHR简介

 

在XHR诞生前,网页要获取客户端和服务器的任何状态更新,都须要刷新一次,在XHR诞生后就能够彻底经过JS代码异步实现这一过程。XHR的诞生也使最初的网页制做转换为开发交互应用,拉开了WEB2.0的序幕。 javascript

XHR是一种浏览器API,极大简化了异步通讯的过程,开发者并不须要关注底层的实现,由于浏览器会为咱们完成这些工做,如链接管理、协议协商、HTTP请求格式化等等。最第一版本的XHR能力很是有限,只支持文本传输,处理上传能力也不足,对于跨域请求也不支持。为解决这些问题,W3C于2008年发布了“XMLHttpRequest Level2”草案,新增了以下功能:html

  • 支持请求超时;
  • 支持传输二进制和文本数据;
  • 支持重写媒体类型和编码响应;
  • 支持监控每一个请求的进度事件;
  • 支持有效的文件上传;
  • 支持安全的跨来源请求。

2011年,W3C将“XMLHttpRequest Level2”规范与最初的“XMLHttpRequest”规范合并,全部XHR2新增的功能也都并入了原来的XHR API中,接口不变,功能加强。java

1.XHR简介

XMLHttpRequest 对象提供了对 HTTP 协议的彻底的访问,包括作出 POST 和 HEAD 请求以及普通的 GET 请求的能力。XMLHttpRequest 能够同步或异步地返回 Web 服务器的响应,而且可以以文本或者一个 DOM 文档的形式返回内容。XHR接口强制要求每一个请求都具有严格的HTTP语义–应用提供数据和URL,浏览器格式化请求并管理每一个链接的完整生命周期,因此XHR仅仅容许应用自定义一些HTTP首部,但更多的首部是不能本身设定的,如:web

  • Accept-Charset, Accept-Encoding, Access-Control-*
  • Host, Upgrade, Connection, Referer, Origin
  • Cookie, Sec-, Proxy-, 及其余首部

浏览器会拒绝绝对不安全的首部重写,以保证应用不能假扮用户代理、用户或请求来源,如Origin由浏览器自动设置,Access-Control-Allow-Origin由服务器设置,若是接受该请求,不包含该字段便可,浏览器发出的请求将做废。json

  • CORS请求会省略cookie和HTTP认证等用户凭据;
  • 客户端被限制只能发送“简单的跨域请求”,包括只能使用GET POSD HEAD三种方式,只能访问经过XHR发送并读取的HTTP首部。

若是想要启用cookie和HTTP认证,客户端必须在发送请求时经过XHR对象发送额外的属性(withCredentials),而服务器也须要以Access-Control-Allow-Credentials响应,表示容许应用发送隐私数据。一样,若是客户须要写入或读取自定义HTTP标头或想要使用“非简单的方法”的请求,那么它必须首先经过发出一个预备请求,以获取第三方服务器的许可,以下所示:跨域

 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
// 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获取一张图片,并显示到网页上的示例:缓存

 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
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格式数据:安全

1
2
3
4
5
6
7
8
9
10
11
12
13
14
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.数据分片上传:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
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: 协议的状况下是无效的。服务器

转载自:http://www.cnblogs.com/syfwhu/p/6116323.html

相关文章
相关标签/搜索