jsonp跨域原理解析

首先我们就来看下jsonp是如何突破同源策略的限制实现跨域的

先,不知道大家有没有注意,不管是我们的script标签的src还是img标签的src,或者说link标签的href他们没有被通源策略所限制,比如我们有可能使用一个网络上的图片,就可以请求得到

<img src="https://ss3.baidu.com/9fo3dSag_xI4khGko9WTAnF6hhy/image/h%3D300/sign=6d0bf83bda00baa1a52c41bb7711b9b1/0b55b319ebc4b745b19f82c1c4fc1e178b8215d9.jpg">

src或href链接的静态资源,本质上来说也是一个get请求,拿csdn上的静态资源举例

 

 

可以看到,确实是个get请求无疑。同理img标签的src和link标签的href也会发送一个get请求去请求静态资源。那么我们通过这点,是不是发现了点什么,这些标签的src和link属性,并没有受同源策略的限制。说到这里jsonp的实现原理就浮出水面了。

jsonp就是使用通源策略这一“漏洞”,实现的跨域请求(这也是jsonp跨域只能用get请求的原因所在)。想象一下,既然是个get请求,那么服务端一定可以接收到,并做出反馈。ok,知道这两点之后,我们开始具体使用jsonp进行跨域请求。

JSONP跨域实现:
根据上边所说的,我们要用过利用img、srcipt,link标签的src或href属性(到底使用那个标签无所谓)来实现,那么我们如何做呢,我们来看一段简单的代码,为了方便,我这里使用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);
        });

可以看到,让我们点击按钮的时候,创建了一个script标签(即会发送一个get请求到src指向的地址),src地址是"localhost:3000/article-list",这个src地址,就是我们请求的服务端接口。注意,这里我们有是那个参数,name,age和callback,name和age不说了,这跟我们平时普通的get请求参数无异。主要说下callback这个参数,callback参数就是核心所在。为什么要定义callback呢?首先我们知道,这个get请求已经被发出去了,那么我们如何接口请求回来的数据呢,callback=func则可以帮我们做这件事。我们继续看下边的代码

<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+'岁了');
}

这里可以看到,我们声明了一个func函数,但没有执行,你可以想一下,如果服务端接口到get请求,返回的是func({message:'hello'}),这样的话在服务端不就可以把数据通过函数执行传参的方式实现数据传递了吗。

服务端代码实现:

接下来,我们看服务端应该如何实现:

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 + ')');
});

ok,接下来当我们点击提交的时候,就获取到了服务端反回的数据。如下:

 

 

总结:

需要注意的是,callback参数定义的方法是需要前后端定义好的,具体什么名字,商讨好就可以了。其实jsonp的整个过程就类似于前端声明好一个函数,后端返回执行函数。执行函数参数中携带所需的数据,整个过程实际非常简单易懂

原文链接:https://blog.csdn.net/badmoonc/article/details/82289252

原文地址:https://www.cnblogs.com/yangwenbo/p/11457344.html