jsonp的跨域原理解析
背景:
由于浏览器同源策略的限制,非同源下的请求,都会产生跨域问题,jsonp就是为了解决这个问题而出现的一种便捷的解决方案。
所谓的同源策略:同一协议,同一域名,同一端口号。当其中一个不同的时候,就会产生跨域问题
突破同源策略
知道了同源策略,下面就介绍jsonp是如何实现突破同源策略的。
首先,这个解决方法是通过一个现象。大家应该都有发现,不管我们是script
的src
还是img
的src
,或者说是link
标签的href
他们都没有被同源策略所限制。
比如
<img src="https://ss3.baidu.com/9fo3dSag_xI4khGko9WTAnF6hhy/image/h%3D300/sign=6d0bf83bda00baa1a52c41bb7711b9b1/0b55b319ebc4b745b19f82c1c4fc1e178b8215d9.jpg">
又或者是一些静态资源的请求
image我们可以发现,通过这种方式去GET请求,并没有被同源策略限制。这其实就是jsonp的实现原理。
jsonp就是利用这一现象的"漏洞",实现的跨域请求。(同时这也是为什么jsonp只能接受get请求的原因)
既然是一个get请求,那么假设服务端一定可以接收到,并且做出反馈,再这个假设的前提下,下面介绍如何实现。
JSONP跨域实现
根据上文所描述,我们需要利用script
标签或者是img
link
标签去实现。那么我们就可以有如下的代码(这里为了精简利用了JQuery):
$('#btn').click(function(){
var frame = document.createElement('script');
frame.src = 'http://localhost:3000/article-list?name=leo&age=30&callback=func';
$('body').append(frame);
});
可以看到,当我们点击id
为btn
的按钮时,会创建一个script标签,并且设置里面src
的属性为我们要请求的服务端的接口
,并且携带了参数name
和age
还有一个回调函数callback
,这个接下来会介绍到他的用处。
关于callBack,首先我们知道这个get已经发送出去了,我们为了处理接口请求回来的数据所以设置了这个callback
。
<button id="btn">点击</button>
<script src="https://cdn.bootcss.com/jquery/3.3.1/jquery.min.js"></script>
<script>
$('#btn').click(function(){
var frame = document.createElement('script');
frame.src = 'http://localhost:3000/article-list?name=leo&age=30&callback=func';
$('body').append(frame);
});
function func(res){
alert(res.message+res.name+'你已经'+res.age+'岁了');
}
</script>
这里我们声明了一个func
函数,但并没有执行。假设当服务端返回的数据是func({message:'success'}),这样的话,我们不就可以通过函数执行参的方式,来实现数据传递了吗
服务端的实现
下面是服务端的具体实现
router.get('/article-list', (req, res) => {
console.log(req.query, '123');
let data = {
message: 'success!',
name: req.query.name,
age: req.query.age
}
data = JSON.stringify(data)
res.end('func(' + data + ')');
});
当我们提交请求后,会获取到服务端的数据,如下
image就这样,我们完成了jsonp的跨域。
总结
所谓的JSONP本质就是利用script
img
link
这些标签的src或者href属性在请求资源的时候不会受到同源策略所限制这一特性,来实现跨域请求。同时需要注意的是前后端需要一同协商好回调函数的函数名,还有就是只能处理GET请求。
网友评论