前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >WEB性能(7)--XMLHttpRequest

WEB性能(7)--XMLHttpRequest

作者头像
从入门到进错门
发布2019-10-22 14:44:15
8620
发布2019-10-22 14:44:15
举报

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。

本文链接:https://blog.csdn.net/caomage/article/details/101906193

一、XMLHttpRequest

XMLHttpRequest(XHR)是浏览器层面的API,可以让开发人员通过JavaScript实现数据传输。XHR是在Internet Explorer 5 中首次亮相的,后来成为AJAX(Asynchronous JavaScript and XML)革命核心技术,我今天几乎所有Web应用必不可少的基本构件。 XHR诞生以前,网页要获取客户端和服务器的任何状态更新,都需要刷新一次。有了XHR,这个过程就可以异步实现,而且完全通过应用的JavaScript代码完成。 然而,XHR的能力不仅仅表现在能实现浏览器的异步通信,还表现在它极大的简化了这个异步通信过程。XHR是浏览器提供的API,这就意味着浏览器会自动帮我们完成所有底层的连接管理、协议协商、HTTP请求格式化等等很多工作。

二、跨域资源共享–CORS

XHR是一个浏览器层面的API,向我们隐藏了大量底层处理,包括缓存、重定向、内容协商、认证,等等。这样做有两个目的:

  1. XHR的API因此非常简单.
  2. 浏览器可以采用沙箱机制,对应用代码强制施加一套安全限制。

虽然XHR API允许应用添加自定义的HTTP首部(通过setRequestHeader()方法),同时也有一些首部是应用代码不能设定的:

Accept-Charset Accept-Encoding Access-Control Host Upgrade Connection Referer Origin 等等

浏览器会拒绝对不安全首部的重写,以此保证应用不能假扮用户代理、用户或请求来源。事实上,保护来源(Origin)首部特别重要,因为这是对所有XHR请求应用“同源策略”的关键。 一个“源”有协议、域名和端口这三个要素共同定义。同源策略的出发点很简单:浏览器存储着用户数据,比如认证令牌、cookie以及其他私有数据,这些数据不能泄漏给其他应用。如果没有同源沙箱,那么不同源的网站内的脚步就能相互访问用户数据。

在这里插入图片描述
在这里插入图片描述

可是,在某些必要的情况下,同源策略也会给更好的利用XHR带来的麻烦:如果服务器想要给另一个网站中的脚本提供资源怎么办?这就是Cross-Origin Resource Sharing(跨域资源共享,CORS)的来由。CORS针对客户端的跨域资源请求提供了安全的后门。 CORS也使用相同的XHR API,区别在于请求资源用的URL与当前执行的脚本来自不同的源。针对CORS请求的选择同意认证机制由底层处理:请求发出后,浏览器自动追加受保护的Origin首部,相应地,服务器可以检查该首部,决定是否接受该请求,如果接受就返回Access-Control-Allow-Origin响应首部。如果响应中不包含Access-Control-Allow-Origin,客户端就会自动将发出的请求作废。如果第三方服务器不支持CORS,那么客户端端的请求同样会作废,因为客户端会验证响应中是否包含选择同意的首部。作为一个特列,CORS还允许服务器返回一个通配值(Access-Control-Allow-Origin: * ),表示它允许来自任何源的请求。

当然,CORS还会提前采取一系列措施保证安全:

  1. CORS请求会忽略cookie和HTTP认证等用户凭据。
  2. 客户端被限制只能发送“简单的跨域请求”,包括只能使用GET、POST和HEAD,以及只能访问可以通过XHR发送并读取的HTTP首部。

如果想要启用cookie和HTTP认证,客户端必须在发送请求时通过XHR对象发送额外的属性(withCredentials),而服务器也必须用适当的首部(Access-Control-Allow-Credentials)响应,表示它允许应用发送用户的隐私数据。类似的,如果客户端需要写或者读自定义的HTTP首部,或者想要使用“不简单的方法”发送请求,那么必须要先获得第三方服务器的许可,即向第三方服务器发送一个预备(preflight)请求。

在这里插入图片描述
在这里插入图片描述

三、通过XHR下载数据

XHR既可以传输文本数据,也可以传输二进制数据。事实上,浏览器可以自动为各种原生数据类型提供编码和解码服务,因此在应用中直接将这些数据传给XHR时就已经编码/解码好了。浏览器可以自动解码的数据类型如下:

  1. ArrayBuffer,固定长度的二进制数据缓冲区;
  2. Blob,二进制大对象或不可变对象;
  3. Document,解析后得到HTML或XML文档;
  4. JSON,表示简单数据结构的JavaScript对象;
  5. Text,简单的文本字符串。

浏览器可以依靠HTTP的content-type首部来推断适当的数据类型,应用也可以在发起XHR请求时显示重写数据类型。

在这里插入图片描述
在这里插入图片描述

四、通过XHR上传数据

通过XHR上传任何类型的数据都很简单,而且高效。事实上,上传不同类型数据代码都一样,只不过最后在调用send()方法时,传入的数据对象不同而已。

在这里插入图片描述
在这里插入图片描述

五、监控下载和上传进度

网络连接可能会中断,而延迟和带宽也不稳定。因此,需要一些事件来监听请求的状态。

在这里插入图片描述
在这里插入图片描述

每个XHR请求开始时都会触发loadstart事件,而结束时都会触发loadend事件。在这两件事之间,还可能触发一或多个其他事件,表示传输状态。因此,要监控进度,可以子啊XHR对象上注册一系列JavaScript事件监听器。无论load和error中的哪一个被触发,都代表XHR传输的最终状态,而progress事件则可能被触发任意多次,这就为监控传输状态提供了便利。 要估算传输的数据量,服务器必须在其响应中提供内容长度(content-length)首部。而对于分块数据,由于响应的总长度未知,因此就无法估计长度了。另外,XHR请求默认没有超时限制,这意味着一个请求的进度可以无限长。作为最佳实践,一定要设置适当的超时时间,并处理错误。

六、实时通知与交付

XHR提供了一种简单有效的客户端与服务器同步的方式:必要时,客户端可以向服务器发送一个XHR请求,以更新服务器上的数据。然而,实现同样但相反的操作却更困难一些。如果服务器数据更新了,那怎么通知客户端呢? HTTP没有提供服务器向客户端发起连接的方式。因此,为实时接受数据,客户端必须轮询服务器。实时对不同的应用有不用的含义:有些应用要求毫秒级的精确度,而有些应用可能只要几分钟同步一次就够了。

通过XHR实现轮询

从服务器取得更新的一个最简单的方法,就是客户端定时发起XHR请求,也就是轮询(polling)。如果服务器有新数据,返回新数据,否则返回空。 轮询实现起来简单,但也经常效率很低。其中关键在于选择轮询间隔:长轮询间隔意味着延迟交付,而断轮询间隔会导致客户端与服务器不必要的流量和协议开销。最佳轮询间隔时多少?没有唯一的答案。轮询频率取决于应用的需要。

七、XHR使用场景及性能

XMLHttpRequest是我们从在浏览器中做网页转向开发web应用的关键。首先,它让我们在浏览器中实现了异步通信,但同样重要的是,它还把这个过程变得非常简单。分派和控制HTTP请求只要几行JavaScript代码,而其他负责的工作都交给浏览器了:

  1. 浏览器格式化HTTP请求并解析响应;
  2. 浏览器强制施加相关的安全(同源)策略;
  3. 浏览器处理内容协商(如gzip压缩);
  4. 浏览器处理请求和响应的缓存;
  5. 浏览器处理认证、重定向……

不过,XHR也有自身的局限性,比如不适合流式数据处理。此外,也没有最好的方式通过XHR实时交付更新。定时轮询会导致高开销和更新延迟。长轮询的延迟低,但每次更新仍然有开销,因为每次更新都需要一次HTTP请求。

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2019-10-02 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 一、XMLHttpRequest
  • 二、跨域资源共享–CORS
  • 三、通过XHR下载数据
  • 四、通过XHR上传数据
  • 五、监控下载和上传进度
  • 六、实时通知与交付
    • 通过XHR实现轮询
    • 七、XHR使用场景及性能
    领券
    问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档