1. 图像Ping
图像 Ping 是与服务器进行简单、单向的跨域通信的一种方式。只能发生”get”请求,不能访问响应文本。
请求的数据是通过查询字符串形式发送的,但浏览器接收不到任何响应的内容,但可以侦听响应什么时候接收到。
1
2
3
4
5var img = new Image();
img.onload = img.onerror = function(){
alert("Done!");
};
img.src = "http://www.example.com/test?name=Nicholas";图像 Ping最常用于跟踪用户点击页面或动态广告曝光次数。
2. JSONP
JSONP 是 JSON with padding(填充式 JSON 或参数式 JSON)的简写,是应用JSON的一种新方法.
JSONP 由两部分组成:回调函数和数据。回调函数是当响应到来时应该在页面中调用的函数。回调函数的名字一般是在请求中指定的。而数据就是传入回调函数中的 JSON 数据。
1
2
3
4
5
6
7function handleResponse(response){
alert("You’ re at IP address " + response.ip + ", which is in " +
response.city + ", " + response.region_name);
}
var script = document.createElement("script");
script.src = "http://freegeoip.net/json/?callback=handleResponse";
document.body.insertBefore(script, document.body.firstChild);两点不足:一是不安全,二是确定JSONP请求是否失败并不容易。
3. Comet
Comet则是一种服务器向页面推送数据的技
术,能够让信息近乎实时地被推送到页面上,非常适合处理体育比赛的分数和股票报价。++
有两种实现 Comet 的方式:长轮询和流。
- 长轮询
短轮询是服务器立即发送响应,无论数据是否有效。
长轮询是等待发送响应。
- HTTP流
什么是http流:浏览器向服务器发送一个请求,而服务器保持连接打开,然后周期性地向浏览器发送数据.
关键:所有服务器端语言都支持打印到输出缓存然后刷新(将输出缓存中的内容一次性全部发送到客户端)的功能。
实现:通过侦听readystatechange事件及检测readyState的值是否为3,IE除外。
1 | function createStreamingClient(url, progress, finished){ |
改善:comet容易出错,且浏览器社区认为 Comet 是未来 Web 的一个重要组成部分,为了简化这一技术,又为 Comet 创建了两个新的接口。
4. 服务器发送事件
SSE(Server-SentEvents,服务器发送事件)是围绕只读 Comet交互推出的 API或者模式。
SSE API用于创建到服务器的单向连接,服务器通过这个连接可以发送任意数量的数据。
不支持IE。
4.1 SSE API
要预订新的事件流,首先要创建一个新的 EventSource对象,并传进一个入口点,传入的URL必须同源:
1 | var source = new EventSource("myevents.php"); |
EventSource 的实例有一个readyState属性:
- 0:表示正连接到服务器
- 1:表示打开了连接
- 2:表示关闭了连接
EventSource 的实例有以下三个事件:
- open:在建立连接时触发。
- message:在从服务器接收到新事件时触发。
- error:在无法建立连接时触发。
服务器发回的数据以字符串形式保存在event.data 中。
1 | source.onmessage = function(event){ |
想强制立即断开连接并且不再重新连接,可以调用 close()。
4.2 事件流
服务器事件会通过一个持久的HTTP响应发送,这个响应的MIME类型为text/event-stream。
响应的格式是纯文本,最简单的情况是每个数据项都带有前缀 data:。如下
1
2
3
4
5
6data: foo
data: bar
data: foo
data: bar只有在包含data:的数据行后面有空行时,才会触发 message事件,因此在服务器上生成事件流时不能忘了多添加这一行。
设置ID,可以保证多次连接事件流顺序正确。
5. Web Sockets
Web Sockets的目标是在一个单独的持久连接上提供全双工、双向通信。
使用自定义协议,ws://和wss://
优缺点:
- 好处是,能够在客户端和服务器之间发送非常少量的数据,而不必担心HTTP那样字节级的开销。适合移动应用。
- 坏处是,安全隐患。
5.1 Web Sockets API
要创建 Web Socket,先实例一个 WebSocket 对象并传入要连接的 URL,传入绝对URL:
1 | var socket = new WebSocket("ws://www.example.com/server.php"); |
实例化了 WebSocket 对象后,浏览器就会马上尝试创建连接。
表示当前状态的属性:
- WebSocket.OPENING (0):正在建立连接。
- WebSocket.OPEN (1):已经建立连接。
- WebSocket.CLOSING (2):正在关闭连接。
- WebSocket.CLOSE (3):已经关闭连接。
5.2 发送和接收数据
发送数据
- 要向服务器发送数据,使用
send()
方法
并传入任意字符串。 - Web Sockets只能通过连接发送纯文本数据,对于复杂的数据结构,在通过连接发送之前,必须进行序列化成一个JSON字符串
1
2
3
4
5
6
7
8var socket = new WebSocket("ws://www.example.com/server.php");
var message = {
time: new Date(),
text: "Hello world!",
clientId: "asdfp8734rew"
};
socket.send(JSON.stringify(message));
- 要向服务器发送数据,使用
接收数据
当服务器向客户端发来消息时,WebSocket 对象就会触发 message 事件。1
2
3
4
5socket.onmessage = function(event){
var data = event.data;
//处理数据
};
5.3 其他事件
WebSocket 对象还有其他三个事件,在连接生命周期的不同阶段触发。
- open:在成功建立连接时触发。
- error:在发生错误时触发,连接不能持续。
- close:在连接关闭时触发。
6. SSE与Web Sockets
考虑是使用 SSE还是使用 Web Sockets时,可以考虑如下几个因素:
- 是否有自由度建立和维护 Web Sockets服务器
- 需不需要双向通信