Asynchronous JavaScript And XML
Ajax的核心是XMLHttpRequest对象,简称XHR
IE7+ 及主流浏览器都支持原生的XHR对象,可以通过构造函数XMLHttpRequest()来创建XHR对象
还需要支持跟早的版本就需要加入对原生XHR对象的支持
XHR用法
使用XHR对象时要调用的第一个方法为open()
参数有三个发送请求的类型(post,get等),请求的URL 和一个是否异步发送请求的布尔值,open()
方法并不是真正发送请求,而只是一个启动请求以备发送,然后调用send()
send
接收一个参数,即要作为请求主体发送的数据,若果不需要请求主题发送数据必须传入,因为这个参数对浏览器来说是必须的,服务器响应之后将响应数据自动填充到XHR对象的属性,相关属性
responseText/responseXML/status/statusText
//Http请求状态码
200 请求成功
304 请求的资源并没有被修改,可以直接使用浏览器中缓存的版本
通过status
来判断接下来要执行操作,也可以检测XHR对象的readyState属性,该属性表示请求或者响应过程中的当前活动阶段
0: 未初始化,尚未调用open()
1: 启动,已经调用open,但未send()
2: 发送,已经调用send() 但尚未接收到响应
3: 接收,已经接收到部分响应数据
4: 完成,已经接收到全部的响应数据
只能向同一个域中使用相同的端口和协议的URL发送请求—–所以导致跨域问题
HTTP头部信息
每个HTTP请求和响应都会带有响应的头部信息,默认情况下在发送XHR请求的同时,还会发送下列头部信息
Accept: 浏览器能够处理的的内容类型
Accept-Charset: 浏览器能够显示的字符集
Accept-Encoding: 浏览器能够处理的压缩编码
Accept-Language: 浏览器当前设置的语言
Connection: 浏览器与服务器之间的链接类型
Cookie: 当前页面设置的所有Cookie
Host: 发出请求页面所在的域
Reference: 发出请求页面的URI
User-Agent: 浏览器的用户代理字符串
每个浏览器实际发送的头部信息不同,但上面的基本是所有浏览器都会发送的
XHR对象的方法
setRequestHeader()
可以设置自定义的请求头部信息
getAllResponseHeaders()
获取一个包含所有头部信息的长字符串
GET请求
最常用的,用来向服务器查询信息,必要的将查询字符串追加到URL末尾,查询的字符串中的每个参数的名称和值必须使用encodeURIComponent()
进行编码,多个name=value之间用&连接
POST请求
通常向服务器发送应该保存的数据,将查询字符串保存到HTTP消息主体中发送
XMLHttpRequest 2级
所有浏览器实现了部分内容
FormData: 为序列化表单以及创建与表单格式相同的数据提供了遍历
IE8+ 添加了一个timeout
属性,设置超时响应
进度事件
loadstart: 接收到响应数据的第一个字节时触发
progress: 接收响应期间不停的触发
error:请求发生错误时触发
abort: 因为调用abort()方法而终止连接时触发
load: 接收到完整的响应数据时触发
loadend: 通信完成时触发,或者触发error,abort,load事件后触发
跨域资源共享 ## CORS(cross-origin resource sharing)
在发送一个请求的时候需要额外给头部添加一个Origin
,其中包含页面的源信息,以便服务器根据这个头部信息来决定是否给与响应,如果服务器认为这个请求可以接收,就在Access-Control-Allow-Origin
头部中回相同的源信息
IE8 通过XDR(XDomainRequest)对象,创建实例然后调用open()两个参数,send()
其他浏览器的实现: XMLHttpRequest() 来实现
其他跨域技术
图像Ping: 动态创建图像,Image()实例,为实例的src添加一个跨域的URL,只能发送GET请求,无法访问服务器的响应文本
JSONP :JSON with padding,通过动态<script>
元素实现,可以为src添加一个跨域的URL
Comet : 一种服务器向页面推送数据的技术,两种方式长轮询
和流
。长轮询是页面发送一个请求,然后服务器一直保持打开,直到有数据可发送,发送完数据后,浏览器关闭链接,随即又发起另一个请求。使用setTimeout()就能实现,而你要做的就是决定何时发送,短轮询就是立即做出响应,无论数据是否有效
HTTP流
:在页面的整个生命周期内只使用一个HTTP连接,就是向服务器发送请求,服务器一直保持连接打开,然后周期性的向浏览器发送数据
所有浏览器都支持打印到输出缓存然后刷新,Firefox,Safari,Opera,Chrome中通过侦听readystatechange
事件及检测readystate === 3
就可以利用XHR对象实现HTTP流,在上述的浏览器中随着不断的从服务器接收数据,readystate的值会周期性的变为3,当readystate为3的时候,responseText属性就会保存接收到的所有数据,此时就需要比较之前接收到的数据,决定从什么位置开始取新的数据
SSE 服务器发送事件
Firefox6+ Safari5+ Opera11+ chrome IOS4+
创建到服务器的单向连接,服务器可以通过这个连接发送任意数量的数据,服务器相应的MIME必须是text/event-stream
,而且浏览器中的JS能够解析格式输出,支持短长轮询和HTTP流
先创建一个EventSource
对象,并传入一个入口, 实例有个readystate属性,0:正在连接到服务器 1:打开连接了2: 关闭了连接 另外还有三个事件open/message/error
建立连接时触发/从服务器接收到新事件触发/无法建立连接时触发
Web Sockets
全双工,双向通信
使用了自定义协议 ws://
加密连接wss://
传递的数据包很小,非常适合移动端,
var socket = new WebSocket("ws://www.xxx.com/index.html");
也有一个表示当前状态的readystate属性
WebSocket.OPENING(0): 正在建立连接
WebSocket.OPEN(1): 已经建立连接
WebSocket.CLOSING(2): 正在关闭连接
WebSocket.CLOSE(3): 已经关闭连接
发送数据 send()
,当服务器向客户端发送来消息时触发message事件
socket.onmessage = function(event){
var data = event.data;
}
其它事件open/error/close
WebSocket双向通信(如聊天室),WebSocket协议不同于HTTP,所哟现在的服务器不能用于WebSocket通信,SSE倒是通过常规的HTTP通信,因此现在的服务器都满足需求
/getuserinfo.php?id=23
这个请求结果返回Id为23的用户的某些数据,谁也无法保证别人会将这个URL的Id改为其他的值,因此getuserinfo.php必须知道请求者是否有权限要访问请求的数据,否则任何人的数据都可能被泄露出去
为确保访问的URL安全,做法就是验证发送请求者是否有权限访问响应的资源
要求以SSL连接访问可以通过的XHR请求资源
要求每一次请求都要附带经过响应算法计算得到的验证码
要求发送POST而不是GET请求
检查URL来源以确认是否可靠-很容易伪造
基于cookie信息进行验证-同样容易伪造