-
XMLHttpRequest
对象 -
XMLHttpRequest
2级 - 进度事件
- 跨源资源共享
- 其他跨域技术
Ajax,即 Asynchronous JavaScript + XML,能够向服务器取得数据而无需重新刷新页面。Ajax 技术的核心是XMLHttpRequest
对象,使用XHR
对象取得新数据,再通过DOM将新数据插入到页面中。XHR
属性包括:
-
readyState
请求/响应过程的当前活动阶段 -
responseText
作为响应主体被返回的文本 -
status
响应的 HTTP 状态 -
statusText
HTTP 状态的说明
只要readyState
的值由一个值变为另一个值,都会触发一次onreadystatechange
事件
var xhr = new XMLHttpRequest()
xhr.onreadystatechange = function() {
if(xhr.readyState == 4){
if ((xhr.status >= 200 && xhr.status < 300) || xhr.status == 304) {
alert(xhr.responseText)
} else {
alert("Request was unsuccessful:" + xhr.status)
}
}
}
xhr.open("get", "example.txt", true)
xhr.send(null)
使用XHR
时,要调用的第一个方法是open()
,接收三个参数,要发送的请求类型,请求的URL和表示是否异步发送请求的布尔值。
xhr.open("get", "example.php", false) //启动一个针对 example.php 的 GET请求
xhr.send(null)
send()
方法接收一个参数,即要作为请求主体发送的数据,如果不需要通过请求发送数据,则必须传入null
HTTP头部信息,默认情况下,在发送XHR
请求的同时,还会发送下列头部信息:
-
Accept
浏览器能够处理的内容类型 -
Accept-Charset
浏览器能显示的字符集 -
Accept-Language
浏览器能够处理的压缩编码 -
Connection
浏览器与服务器之间的连接类型 -
Cookie
当前页面设置的任何Cookie
-
Host
发出请求的的页面所在域 -
Referer
发出请求的页面的 URI -
User-Agent
浏览器的用户代理字符串
使用setRequestHeader()
方法可以设置自定义请求头部信息,方法接收两个参数:头部字段名称和头部字段值,要成功发送请求头部信息,必须在调用open()
方法之后且调用send()
方法之前调用setRequestHeader()
。调用XHR
对象的getResponseHeader()
方法并传入头部字段名称,可以取得相应的相应头部信息,调用getAllResponseHeaders()
可以取得包含所有头部信息的长字符串。
GET
用于向服务器查询某些信息,将查询字符串参数追加到 URL 的末尾,将信息发送给服务器。
// 向现有URL的末尾添加字符串查询参数
function addURLParam(url, name, value) {
url += (url.indexOf("?") == -1 ? "?" : "&")
url += encodeURIComponent(name) + "=" + encodeURIComponent(value)
return url
}
POST
请求用于向服务器发送应该被保存的数据,将数据作为请求的主体提交
新版的XMLHttpRequest
做了一些改进
- Ajax 操作用来传递表单数据,
FormData
能够序列化表单,创建与表单格式相同的数据
var data = new FormData()
data.append("name", "siyuan")
- 可以设置 HTTP 请求的时限,将最长等待事件设置为3000毫秒,过了这个时限,自动停止 HTTP 请求,触发相应的回调函数
xhr.timeout = 3000
xhr.ontimeout = function(event) {
alert("请求超时")
}
- 可以实现跨域请求,请求不同域名下的数据
- 可以上传文件
- 获取服务端的二进制数据,
overrideMimeType()
方法重写XHR
响应的MIME
类型 - 获得数据传输的进度信息,与
progress
事件相关的五个事件,可以分别指定回调函数,load
,loadstart
,loadend
,abort
,error
,可以分别指定回调函数
跨域资源共享
默认情况下,XHR
对象只能访问与包含它的页面位于同一个域中的资源,实现合理的跨域请求对开发某些浏览器的应用程序至关重要。
CORS
跨域资源共享CORS,定义了在必须访问跨域资源时,使用自定义的HTTP头部让浏览器与服务器进行通信,决定请求或响应是应该成功,还是应该失败。浏览器将CORS请求分为简单请求和非简单请求,只要同时满足以下两个条件,就属于简单请求:
1)请求方法是HEAD
,GET
,POST
之一
2)HTTP的头信息不超过以下字段:Accept
,Accept-Language
,Content-Langugae
,Content-Type
只限于application/x-www-form-urlencoded
、multimultipart/form-data
、text/plain
,Last-Event-ID
简单请求与非简单请求的处理JSONP
JSONP 是通过动态<script>
元素,使用时为src
属性指定一个跨域url
,有能力不受限制地从其他域中加载资源。JSONP是有效的JavaScript代码,在请求完成后,JSONP 响应加载到页面中以后,会立即执行。JSONP由回调函数和数据组成,回调函数是在响应到来时应该在页面中调用的函数,回调函数的名字一般在请求中指定,数据就是传入回调函数中的JSON数据。服务器收到请求后,将数据放在回调函数的参数位置返回。JSONP 从其他域中加载代码执行,如果其他域不安全,会在响应中夹带一些恶意代码,此时只能完全放弃 JSONP 调用。
function handleResponse(response) {
}
var srcipt = document.createElement("script")
script.src = "http://freegeoip.net/json/?callback=handleResponse"
document.body.insertBefore(script, document.body.firstChild)
-
Comet
Comet是一种服务器向页面推送数据的技术,能够让信息实时地被推送到页面上,非常适合处理体育比赛的分数和股票报价。有两种实现Comet的方式:长轮询和流。长轮询是指页面发起到服务器的请求,服务器保持连接打开,直到有数据可发送,发送完数据之后,浏览器关闭连接,随即发送一个到页面的新请求,这个过程在页面打开期间一直持续不断。HTTP流在页面的整个生命周期只使用一个HTTP连接,浏览器向服务器发送一个请求,服务器保持连接打开,周期性地向浏览器发送数据。所有浏览器都支持长轮询,只有部分浏览器原生支持HTTP流。服务器发送事件SSE是一种实现Comet交互的浏览器API,即支持长轮询,也支持HTTP流,用于创建到服务器的单向连接,服务器通过这个连接可以发送任意数量的数据。
function createStreameingClient(url, progress, finished) {
//接收三个参数:要连接的url, 接收到数据时调用的函数, 关闭连接时调用的函数
var xhr = new XMLHTtpRequest()
var received = 0
xhr.open("get", url, true)
xhr.onreadystatechange = function() {
var res
if (xhr.readyState == 3) {
res = xhr.responseText.substring(res)
received += res.length
progress(res)
} else if (xhr.readyState == 4) {
finished(xhr.responseText)
}
}
xhr.send(null)
return xhr
}
-
Web Sockets
Web Sockets能够在一个单独的持久连接上提供全双工、双向通信,在JavaScript 中创建了Web Sockets之后,会有一个HTTP请求发送到浏览器以发起连接,在取得服务器的响应之后,建立的连接会使用HTTP 协议升级为 Web Sockets协议,能够在客户端和服务器之间发送非常少量的数据,不必担心HTTP那样的字节级开销。未加密的连接是ws://
,加密的连接是wss://
。必须给Web Sockets构造函数传入绝对URL,同源策略对Web Socket不适用,可以通过它打开任何站点的连接。
var socket = new WebSocket("ws://example.com/server.php")
socket.send("hello world")
socket.close()
WebSocket对象还有open
,error
,close
事件,在连接生命周期的不同阶段触发,适用于聊天室等。对于未被授权的系统有权访问某个资源的情况,称为跨站脚本攻击,可以通过 1)要求以SSL连接来访问可以通过XHR请求的资源,2)要求每一次请求都要附带经过相应算法计算得到的验证码。
此外,如果非同源,共有三种行为受到限制:
- Cookie、LocalStorage、IndexDB无法读取
- DOM无法获得
- Ajax请求不能发送
对于Cookie和iframe的跨域问题,在一级域名相同,二级域名不同的情况下,可以通过设置相同document.domain
,两个网页就可以共享Cookie。
对于网页不同源,就无法拿到对方的DOM的情况,如对于iframe、window.open()
方法打开的窗口,与父窗口无法通信。
- 片段标识符,URL后面的
#
为片段标识符,只改变片段标识符,页面不会重新刷新。将父窗口的信息写入子窗口的片段标识符,子窗口通过haschange
事件得到通知。
//父窗口
var src = originURL + '#' + data
document.getElementById('parentFrame').src = src
window.onhaschange = checkMessage
//子窗口
function checkMessage() {
var message = window.location.hash
...
}
- 浏览器窗口的
window.name
属性,前一个网页设置了这个属性,后一个网页可以读取它 -
window.postMessage
跨文档通信API,第一个参数是要发送的消息,第二个参数是接收消息的窗口