YvetteLau / Step-By-Step

不积跬步,无以至千里;
704 stars 66 forks source link

JSONP原理及简单实现 #30

Open YvetteLau opened 5 years ago

into-piece commented 5 years ago

同源策略

同源协议指的是页面若域名,端口,协议都相同,便具有相同的源。 目的是为了保证用户信息的安全,防止恶意的网站窃取数据。
解决这种同源策略的方法便成为跨域。

JSONP

JSONP是JSON with Padding的略称。允许在服务器端集成Script tags返回至客户端,通过javascript callback的形式实现跨域访问。

原理

利用script标签的src属性调用资源不跨域的特性,向服务端请求同时传一个callback回调方法名作为参数,服务端接受函数名生成返回json格式资源的代码。

实现

<script type="text/javascript">
    // 获取到跨域资源后的回调
    var handleFn = function(data){
        console.log(data)  // JSONP跨域成功返回的资源
    };
    var url = "resource-url?callback=handleFn";
    var script = document.createElement('script');
    script.setAttribute('src', url);
    document.getElementsByTagName('head')[0].appendChild(script); 
</script>
// 服务端
handleFn({
    "date": "2019-6-18",
    "slogan": "夕夕姐真好看",
    "content": "稳坐沙发" 
});
KRISACHAN commented 5 years ago

JSONP(JSON with Padding)是数据格式JSON的一种“使用模式”,可以让网页从别的网域要数据。另一个解决这个问题的新方法是跨来源资源共享。

由于同源策略,一般来说位于server1.example.com的网页无法与 server2.example.com的服务器沟通,而HTML的

riluocanyang commented 5 years ago

JSONP原理及简单实现

JSONP原理

JSONP是解决跨域问题的一种方案,原理如下: 1、利用script标签的src属性实现跨域; 2、然后前端将回调函数作为参数传给服务器,服务器注入参数后再返回。

JSONP简单实现

function jsonp(params) {
  var script = document.createElement('script');
  var url = params.url + '?callback=' + params.callback,;
  script.src = url;
  document.body.appendChild(script);
}
function fn (data) {
  console.log(data)
}
jsonp({
  url: 'your.url',
  callback: fn
})
chongyangwang commented 5 years ago

jsonp定义

JSONP是受限于浏览器的同源策略的一种跨域问题解决方案

原理

利用script标签的src属性 可以不受同源策略的影响,前端需定义一个回调函数,回调函数 作为参数在请求路径中拼接 ,会将请求得到的结果传入回调之中 前端拿到结果 做相应处理

实现

function  jsonp(params){
    var script = document.creamentEleent('script');
    var   url = params.url+'?callback' =  + params.callback;
    script.src=url;
    document.body.appendChild(script)
 }

 function fn(data){
    console.log(data)
  }

  jsonp({
    url:'',
    callback:fn
  })
woyiweita commented 5 years ago

受同源策略的限制,无法跨域完成数据的请求,jsonp是解决跨域数据请求的一种方案。以百度为了,使用如下

<script src="https://sp0.baidu.com/5a1Fazu8AA54nxGko9WTAnF6hhy/su?cb=jQuery110207811318019654161_1560908189983"></script>
<!--cb 是告诉后端,执行的回调函数名-->
<!--jQuery110207811318019654161_1560908189983 是回调函数名 -->

最终的返回结果如下:

    jQuery110207811318019654161_1560908189983({"q":"","p":false,"bs":"","csor":"0","status":770,"s":[]});

然后就可以使用本地编写的回调函数进行数据的处理操作:

    <script>
        function jQuery110207811318019654161_1560908189983(data){
            console.info(data);
            // 数据处理
        }
    </script>

最终完整代码如下:

    <script>
        function jQuery110207811318019654161_1560908189983(data){
            console.info(data);
            // 数据处理
        }
    </script>
    <!-- 这里可根据所需数据动态创建 -->
    <script src="https://sp0.baidu.com/5a1Fazu8AA54nxGko9WTAnF6hhy/su?cb=jQuery110207811318019654161_1560908189983"></script>
hoyong6 commented 5 years ago

底层是引入一个script 标签,页面上创建script 标签。 简单实现

function jsonp(req){
    var script = document.createElement('script');
    var url = req.url + '?callback=' + req.callback.name;
    script.src = url;
    document.getElementsByTagName('head')[0].appendChild(script); 
}

前端简单调用

function hello(res){
    alert('hello ' + res.data);
}
jsonp({
    url : '',
    callback : hello 
});

后端node 简单实现

var http = require('http');
var urllib = require('url');

var port = 8080;
var data = {'data':'world'};

http.createServer(function(req,res){
    var params = urllib.parse(req.url,true);
    if(params.query.callback){
        console.log(params.query.callback);
        //jsonp
        var str = params.query.callback + '(' + JSON.stringify(data) + ')';
        res.end(str);
    } else {
        res.end();
    }

}).listen(port,function(){
    console.log('jsonp server is on');
});
jodiezhang commented 5 years ago

根据同源策略的限制,端口,域名,协议这三者 一个或者多个不同的情况下,就会出现跨域限制。 但是, Githubissues.

  • Githubissues is a development platform for aggregating issues.