21.5 其他跨域技术
一、图像 Ping
根据 img 标签可以从任何网页中加载图像的事实,图像 Ping 创建 Image 实例,在其 src 属性中添加参数,发送到服务器
var img = new Image();
img.onload = img.onerror = function() {
alert('done');
};
img.src = 'http://www.somewhere.com?name=nicholas';
这种方式有两个缺点:
1.只能发送 GET 请求
2.无法访问服务器的响应文本
二、JSONP
JSONP 是将数据以 JSON 的格式放置在回调函数中响应请求,回调函数的名称一般在请求中指定
function handleResponse(response) { //本地定义回调函数,可以访问响应文本
alert('name:' + response.name + ',' + 'age:' +response.age);
}
var script = document.createElement('script');
script.src = 'http://www/somewhere.com?callback=handleResponse'; //请求的参数中携带回调函数的名称
document.body.insertBefore(script,document.body.firstChild);
响应的形式
handleResponse({'name':'zz','age':123});
JSONP 可以访问响应文本,支持浏览器与服务器之间双向通信,但是,由于响应中的内容安全性未知,这种方式存在风险;另外,很难确定 JSONP 请求是否失败(script 元素对 onerror 事件的支持度低)
三、Comet
Ajax 用于向服务器请求数据,Comet 用于服务器向页面推送数据,有两种方式:长轮询和流
传统的短轮询指浏览器周期性地向服务器发起请求,服务器接收到请求后立即进行响应
长轮询也是浏览器周期性地向服务器发起请求,但是服务器会在有数据发送时才会进行响应
HTTP 流在页面整个生命周期中只使用一个 HTTP 连接,即浏览器发起请求后,服务器一直保持连接打开,并周期性地向浏览器发送数据
四、服务器发送事件
为了简单的实现 Comet,有了 SSE(Server-Sent Events,服务器发送事件),这是一个用于创建到服务器的单向连接的 API,服务器响应的 MIME 类型必须是 text/event-stream,支持长轮询、短轮询和 HTTP 流,能够在断开连接时自动确定何时重新连接
var source = new EventSource('myevents.php'); //传入的 URL 必须与创建对象的页面同源
source.onmessage = function(event) {
var data = event.data; //服务器返回的数据以字符串的形式保存在 event.data 中
//处理数据
};
EventSource 的实例有一个 readyState 属性,0表示正在连接到服务器,1表示打开了连接,2表示关闭了连接
另外,有三个事件
事件 | 说明 |
---|---|
open | 在建立连接时触发 |
message | 在从服务器接收到新事件时触发 |
error | 在无法建立连接时触发 |
若要关闭连接,调用 close 方法
source.close();
服务器响应的数据都带有前缀 data:,且每次 message 事件中的数据最后以空行结束,可以为事件添加关联的 ID,这一行位于data 行前后均可
data:foo
id:1
data:bar
data.foo
data.bar
如上所示,第一次触发 event.data 为 ‘foo’,ID 为1,第三次触发 event.data 为 ‘foo\nbar’
如果意外断开连接,浏览器会向服务器发送一个包含 Last-Event-ID 的特殊 HTTP 头部请求,以便服务器知道下一次该触发哪个事件
五、WebSockets
WebSockets 的目标是在一个单独的持久连接上提供一个全双工、双向通信
其 URL 模式有所不同,未加密的连接不再是 http:// 而是 ws://,同样,加密的连接为 wss://
需要支持 WebSocket 的特殊服务器
var ws = new WebSocket('ws://www.example.com.server.php'); //传入的 URL 必须为绝对路径
ws.send('hello world'); //发送数据
var message = {
time: new Date(),
text: 'hello world'
};
ws.send(JSON.stringify(message)); //只能发送纯文本格式的数据,复杂数据需要进行序列化
ws.onmessage = function(event) {
var data = event.data;
//处理数据,event.data 属性中的数据也是字符串格式
};
ws.close(); //关闭连接
WebSocket 也有一个表示当前状态的 readyState 属性,但是没有 onreadystatechange 事件
属性值 | 说明 |
---|---|
WebSocket.OPENING(0) | 正在建立连接 |
WebSocket.OPEN(1) | 已经建立连接 |
WebSocket.CLOSING(2) | 正在关闭连接 |
WebSocket.CLOSE(3) | 已经关闭连接 |
WebSocket 对象除 message 外,还有三个其他的事件
事件 | 说明 |
---|---|
open | 在成功建立连接时触发 |
error | 在发送错误时触发 |
close | 在连接关闭时触发 |
WebSocket 对象不支持 DOM2 级事件监听器,故使用 DOM0 级方法添加事件处理程序
上述三个事件中,只有 close 事件的 event 对象有额外的属性
属性 | 说明 |
---|---|
wasClean | 连接是否已经明确地关闭 |
code | 服务器返回的数值状态码 |
reason | 字符串,包含服务器发回的消息 |
推荐阅读
-
21.5 其他跨域技术
-
利用webpack+vuex+axios这些技术实现跨域请求数据(详细教程)
-
javascript和jQuery中的AJAX技术详解【包含AJAX各种跨域技术】
-
跨域技术(JSONP与CROS)
-
java - ThinkPHP里的表单令牌如何运用到其他项目中,如何防止跨域提交表单,和伪造表单提交呢?
-
HTML5跨域信息交互技术之postMessage代码实例详解
-
java - ThinkPHP里的表单令牌如何运用到其他项目中,如何防止跨域提交表单,和伪造表单提交呢?
-
疯狂的跨域技术
-
疯狂的跨域技术
-
利用webpack+vuex+axios这些技术实现跨域请求数据(详细教程)