之前关于CORS(Cross-Origin Resource Sharing
)我已经翻译了一篇很详细的文章,12bet,如果对于CORS感兴趣的赶快去看看吧。今天就来试试到底怎么跨域吧。
12bet,在CORS
出现之前,要实现Ajax
跨域通信是比较困难的。12博体育,开发人员们想出了一些方法,利用DOM
中能够执行跨域请求的功能,在不依赖XHR
对象的情况下也能发送某种请求。12bet,例如图像ping和JSONP
,这些技术今天仍然被广泛使用,那么我们就来看看吧。
图像ping
12博体育,每天浏览很多的网页,有时候可能会发现某些图片(<img>
)是来自其他网站的,其实你看到的就是一种跨域,由于图片不受“同源策略”限制,我们就可以利用图片进行跨域了。我们将图片的src
属性指向请求的地址,通过监听load
和error
事件,就能知道响应什么时候接受了,响应的数据可以是任意内容,但通常是像素图或204响应。12bet,图像ping的例子如下:
var btn = document.querySelector("https://www.liuwanlin.info/superlin%e7%9a%84%e8%af%bb%e4%b9%a6%e7%ac%94%e8%ae%b0-52/start-ping");
btn.onclick = function(){
var img = new Image();
img.onload = img.onerror = function(obj){
document.querySelector("https://www.liuwanlin.info/superlin%e7%9a%84%e8%af%bb%e4%b9%a6%e7%ac%94%e8%ae%b0-52/result").innerHTML = "finished";
};
img.src = "https://localhost:3000/img?r="+Math.random();
};
服务器端我们使用express
,简单的代码如下:
router.get('/img', function(req, res, next) {
res.send('我是一张图片,我说这句话好像没什么用');
});
效果如下:
这种方式优点是很明显的:兼容性非常好,缺点就是:只能发生GET请求,而且无法获取响应文本。
JSONP
JSONP
是JSON with padding
(填充式JSON)的简写,是应用JSON
的一种方法,看起来和JSON
差不多,只不过是被包含在函数调用中的JSON
,就像下面这样:
callback({name: 'lwl'})
JSONP
由两部分组成:回调函数和数据,回调函数是响应到来时应该在页面中调用的函数,而数据是传入回调函数中的JSON
数据(服务器填充的)。下面就是一个典型的JSONP
请求:
https://example.com/jsonp?callback=handleResponse
JSONP
也是不受“同源策略”限制的,原因和图片ping是一样的,<script>
标签也可以跨越,因此我们可以通过利用JONP
来动态创建<script>
,并将其src指向一个跨域的URL,就可以完成和跨域得服务器之间的通信了。下面就来看一个例子:
var btn2 = document.querySelector("https://www.liuwanlin.info/superlin%e7%9a%84%e8%af%bb%e4%b9%a6%e7%ac%94%e8%ae%b0-52/start-jsonp");
btn2.onclick = function(){
var script = document.createElement("script");
script.src = "https://localhost:3000/jsonp";
document.body.insertBefore(script, document.body.firstChild);
};
function pagefunc(num){
document.querySelector("https://www.liuwanlin.info/superlin%e7%9a%84%e8%af%bb%e4%b9%a6%e7%ac%94%e8%ae%b0-52/result2").innerHTML = "我从服务器获得了一个随机数:"+num;
}
服务器代码:
router.get('/jsonp', function(req, res, next) {
res.send('pagefunc(' + Math.random() + ')');
});
效果如下:
JSONP
是非常简单易用的,与图像ping相比,优点就是能直接访问响应文本,能够在服务器与客户端建立双向通信。但是JSONP
也是有缺点的:JSONP
直接从其他域加载代码执行,如果其他域不安全,可能会在响应中夹带一些恶意代码。其次,要确定JSONP
请求是否失败并不容易,HTML5为<script>
增加了onerror
方法,但是目前支持度还不是很好。
以上两种方法都是比较简单的跨域通信的方法,下一篇我们一起来看comet
吧。
完整代码请看这里