Ajax是一种技术,一种能够向服务器请求额外的数据而无需卸载页面的技术,能够使网页具备更优的用户体验。Ajax技术的核心是XMLHttpRequest对象(XHR)。本文从XHR开始谈起,理解Ajax技术的特点,再对跨域以及Comet等技术进行简要理解和总结。

XMLHttpRequest基本用法

XHR对象有两个常用的方法open和send。open方法用户启动一个HTTP请求,不过它不会真的发送HTTP请求。open方法接收3个参数,分别表示请求的HTTP方法、请求的URL、是否异步。XHR对象的第二个方法send用于发送open所启动的请求。send方法接收1个参数,表示HTTP请求的主体数据。如果发送的是GET请求这种没有附带主体数据的HTTP请求,则传入null即可。如果是POST请求,则传入需要POST的数据。下面是一个简单示例,向/api/data发起一个GET请求,并且是采取异步的方式发送请求,即该请求不会阻塞页面中其他js代码的执行。

var xhr = new XMLHttpRequest()
xhr.open("get", "/api/data", true)
xhr.send(null)

请求得到的响应数据会自动填充到XHR对象的属性上,主要有下面4个属性:

* responseText: 响应主体文本
* responseXML: 如果响应内容类型是"text/xml"或"application/xml", 这个属性中将包含响应数据的XML DOM文档
* status: 响应的HTTP状态码,一般可以将HTTP状态吗200视为成功的标识
* statusText: HTTP状态的说明

XHR对象有1个readyState属性记录了该对象从创建到收到响应数据可能会经历的5种状态,readyState的可能取值如下:

0: 还没有调用open()方法初始化请求

1: 已经调用open()方法但是还没有调用send()方法

2: 已经调用send()方法但是还没有收到响应

3: 收到部分响应数据,还有部分数据没收到

4: 收到全部响应数据,即响应结束,数据完备

当readyState从一个值变到另一个值的时候会触发readystatechange事件,当这个事件触发的时候只需要在事件处理器里面检查一下readyState的值是否为4,当其值为4的时候就可以对响应的数据做后续处理了。给readystatechange事件指定处理器必须在调用open()方法之前完成才能确保跨浏览器兼容性。下面是简单示例。

var xhr = new XMLHttpRequest()
xhr.onreadystatechange = function() {
 if (xhr.readyState === 4) {
  console.log(xhr.status, xhr.responseText)
 }
}
xhr.open("get", "/api/data", true)
xhr.send(null)

XHR对象提供setRequestHeader()方法可以设置请求的自定义HTTP头部信息,该方法接收两个参数,要设置的字段和该字段的值。在调用open()启动一个请求之后并且在send()发送请求之前调用setRequestHeader()才能设置成功。请求得到响应之后,可以通过getResponseHeader()方法获取响应的HTTP头部信息,该方法接收1个参数,即要获取的字段名。而通过getAllResponseHeaders()则可以获得所有头部信息组成的长字符串。下面是简单示例。

var xhr = new XMLHttpRequest()
xhr.onreadystatechange = function() {
 if (xhr.readyState === 4) {
  console.log(xhr.status, xhr.responseText)
  console.log(xhr.getResponseHeader('SomeKey'))
  console.log(xhr.getAllResponseHeaders())
 }
}
xhr.open("get", "/api/data", true)
xhr.setRequestHeader("SomeKey", "SomeValue")
xhr.send(null)

FormData

XMLHttpRequest 2级定义了FormData类型为序列化表单、创建与表单格式相同的数据、用于XHR传输提供便利。FormData提供append()方法可以直接添加数据,该方法接收两个参数键和值。FormData的构造函数可以不传参数,也可以直接传入1个表单元素。传入表单元素之后会利用该表单元素的数据来向FormData对象预先填入键值对。下面是简单示例。

var form = document.getElementById('myForm')
var data = new FormData(form)
data.append('someKey', 'someValue')
var xhr = new XMLHttpRequest()
xhr.onreadystatechange = function() {
 if (xhr.readyState === 4) {
  console.log(xhr.responseText)
 }
}
xhr.open('post', '/api/upload', true)
xhr.send(data)

跨域资源共享

通过XHR实现Ajax通信会遇到一个限制,即跨域安全策略。跨域安全策略限制了“相同域名、相同端口、相同协议”,当XHR想要访问限制之外的资源就会引发安全错误。CORS(Cross-Origin Resource Sharing),跨域资源共享,其思想是通过使用自定义HTTP头部让浏览器与服务器进行沟通从而决定请求或者响应的成功与失败,需要浏览器和服务器同时支持才能实现正常的访问。目前大部分浏览器已经支持了CORS,所以写起代码跟普通的同域资源访问几乎一样,就只是把URL用绝对路径表示。因此,要实现跨域的关键还是在服务器,具体如何实现本文不深入讨论。下面是前端js的简单示例。

var xhr = new XMLHttpRequest()
xhr.onreadystatechange = function() {
 if (xhr.readyState === 4) {
  console.log(xhr.responseText)
 }
}
xhr.open('get', 'http://www.otherserver.com/api/data', true)
xhr.send(null)

JSONP

JSONP(JSON with padding)是应用JSON实现跨域资源访问的一种方法。JSONP由两部分内容组成:回调函数和JSON数据。前面说过,XHR请求会遇到跨域安全策略的限制,但是HTML中的script标签则不会有这个限制,我们可以通过script标签引用不同域里面的js文件。JSONP便是钻了这个空子,它通过动态创建script元素,然后把src指向其他域的URL从而实现加载其他域的资源,然后通过回调函数来处理加载得到的数据。下面是一个简单示例。

function handler(res) {
 console.log(res)
}
var script = document.createElement('script')
script.src = 'http://www.otherserver.com/api/data/"htmlcode">
var source = new EventSource("/api/events")
source.onmessage = function(event) {
 console.log(event.data)
}

如上面代码所示,要向服务器预定事件流获取服务器发送的数据,首先创建EventSource对象,然后在message事件触发的时候进行处理。服务器发送的数据以字符串形式保存在event.data中。EventSource对象会保持与服务器的活动连接,如果中间断开会重新连接,如果要真正地断开连接可以通过调用close()方法来实现。EventSource的message事件会在从服务器收到新事件的时候触发,除了message事件之外它还有另外2个事件open和error,open事件在建立连接的时候触发,error事件在无法建立连接的时候触发。

Web Sockets

Web Sockets是一种与服务器进行全双工双向通信的通道。Web Sockets不适用HTTP协议,而前面说的Ajax和Comet都是使用HTTP协议。篇幅关系本文对Web Sockets不作讨论。

总结

Ajax实现在不加载页面的情况下向服务器请求数据,提升网页的用户体验。实现Ajax技术的XHR会遇到跨域安全策略的限制,通过CORS解决跨域问题需要浏览器和服务器两端的配合。JSONP是一种实现跨域访问的”小技巧“但也是存在一些问题。Comet对Ajax进行了拓展,让服务器能够实时向浏览器推送数据,但从实现来看不管是轮询还是HTTP流,都是浏览器先向服务器发起请求连接。Web Sockets的全双工双向通信也有其特色,以后有时间可以继续了解。

以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,同时也希望多多支持!

华山资源网 Design By www.eoogi.com
广告合作:本站广告合作请联系QQ:858582 申请时备注:广告合作(否则不回)
免责声明:本站资源来自互联网收集,仅供用于学习和交流,请遵循相关法律法规,本站一切资源不代表本站立场,如有侵权、后门、不妥请联系本站删除!
华山资源网 Design By www.eoogi.com

《魔兽世界》大逃杀!60人新游玩模式《强袭风暴》3月21日上线

暴雪近日发布了《魔兽世界》10.2.6 更新内容,新游玩模式《强袭风暴》即将于3月21 日在亚服上线,届时玩家将前往阿拉希高地展开一场 60 人大逃杀对战。

艾泽拉斯的冒险者已经征服了艾泽拉斯的大地及遥远的彼岸。他们在对抗世界上最致命的敌人时展现出过人的手腕,并且成功阻止终结宇宙等级的威胁。当他们在为即将于《魔兽世界》资料片《地心之战》中来袭的萨拉塔斯势力做战斗准备时,他们还需要在熟悉的阿拉希高地面对一个全新的敌人──那就是彼此。在《巨龙崛起》10.2.6 更新的《强袭风暴》中,玩家将会进入一个全新的海盗主题大逃杀式限时活动,其中包含极高的风险和史诗级的奖励。

《强袭风暴》不是普通的战场,作为一个独立于主游戏之外的活动,玩家可以用大逃杀的风格来体验《魔兽世界》,不分职业、不分装备(除了你在赛局中捡到的),光是技巧和战略的强弱之分就能决定出谁才是能坚持到最后的赢家。本次活动将会开放单人和双人模式,玩家在加入海盗主题的预赛大厅区域前,可以从强袭风暴角色画面新增好友。游玩游戏将可以累计名望轨迹,《巨龙崛起》和《魔兽世界:巫妖王之怒 经典版》的玩家都可以获得奖励。