首页 课程 师资 教程 报名

jsonp跨域原理的解析

  • 2022-11-03 09:20:12
  • 277次 星辉

背景:

由于浏览器同源策略的限制,非同源下的请求,都会产生跨域问题,jsonp即是为了解决这个问题出现的一种简便解决方案。

同源策略即:同一协议,同一域名,同一端口号。当其中一个不满足时,我们的请求即会发生跨域问题。

举个简单的例子:

http://www.abc.com:3000到https://www.abc.com:3000的请求会出现跨域(域名、端口相同但协议不同)

http://www.abc.com:3000到http://www.abc.com:3001的请求会出现跨域(域名、协议相同但端口不同)

http://www.abc.com:3000到http://www.def.com:3000的请求会出现跨域(域名不同)

突破同源策略限制:

现在知道了同源策略,那我们就来看下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上的静态资源举例:

$('#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指向的地址,注意:这里必须使用scipt标签,否则返回的数据不会被当作js执行),

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

这里可以看到,我们声明了一个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 + ')');
});

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

这样下来,就完成了实现jsonp的跨域。

选你想看

你适合学Java吗?4大专业测评方法

代码逻辑 吸收能力 技术学习能力 综合素质

先测评确定适合在学习

在线申请免费测试名额
价值1998元实验班免费学
姓名
手机
提交