浅谈跨域(一)——图像Ping和JSONP

在CORS技术出现以前,要实现Ajax跨域通信是比较困难的。开发人员们想出了一些办法,利用DOM中能够执行跨域请求的功能,在不依赖XHR对象的情况下也能发送某种请求。例如图像ping和JSONP。

图像Ping

我们知道,一个网页可以从任何网页加载图像,不用担心跨域不跨域,所以,我们就可以利用图片不受“同源限制”这一点进行跨域通信。
我们利用JS创建一个新的Image对象,并把src属性设置为指向请求的地址,通过监听onload和onerror事件来确定是否接受到了响应。响应的数据可以是任意内容,但通常是像素图或204响应。

需要注意的是,新图像元素只要设置了src属性就会开始下载,所以我们这里的事件一定要在指定src属性之前绑定,这也是为什么我们这里不需要把img标签插入DOM 的原因。

<body>
    <button id="Ping">图像Ping发送请求</button>
    <script>
        var btn=document.getElementById('Ping');
        btn.onclick=function () {
            var img=new Image();
            img.onload=img.onerror=function () {
                alert("Done");
            };
            img.src="http://localhost:8081/img?name=Joy";
        }
    </script>
</body>
//服务器代码
app.get('/img',function (req,res) {
   res.send("我是一张图片");
});

这种方式优点是很明显的:兼容性非常好,缺点就是:只能发生GET请求,而且无法获取响应文本。

JSONP

利用动态脚本插入技术,动态创建script标签,同样是利用src属性,向指定URL发出请求。也就是说,服务器返回的数据就是要插入文档的js代码。在客户端监听onload和onerror事件。
这里要注意的是,不同于img元素,script标签要插入文档后才开始下载。

jsonp由两部分组成:回调函数和数据。回调函数是当响应到来时用该在与面调用的函数,数据是由服务器填充的传入回调函数的json数据,就像下面这样:

callback({"name":"Joy"})
<body>
<button id="jsonp">jsonp发送请求</button>
<div id="result"></div>
<script>
    var btn=document.getElementById('jsonp');
    function handleResponse(response) {
        document.getElementById("result").innerHTML=response;
    };
    btn.onclick=function () {
        var script=document.createElement("script");
        script.src="http://localhost:8081/script?callback=handleResponse";
        document.body.appendChild(script);
    }
</script>
</body>
//服务端代码
app.get('/script',function (req,res) {
    res.send("handleResponse('我是从服务器传来的数据')")
});

相比于图像Ping,JSONP的优势在于:可以能够直接访问响应文本,支持在浏览器和服务器之间的双向通信。 缺点是:JSONP直接从其他域加载代码执行,如果其他域不安全,可能会在响应中夹带一些恶意代码。其次,要确定JSONP请求是否失败并不容易,HTML5为script增加了onerror方法,但是目前支持度还不是很好。

代码地址:https://github.com/zjjxj/crossDomain-demos

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值