美文网首页IT修真院-前端
跨域解决方案之jsonp

跨域解决方案之jsonp

作者: xiaoyudesu | 来源:发表于2017-08-20 21:55 被阅读0次

    1.背景介绍

    所有支持Javascript的浏览器都会使用同源策略这个安全策略。导致我们无法直接访问非同源的链接,无法取得非同源的数据,但在项目中我们的数据经常写在另一个源中,于是我们需要突破同源限制,取得其他源的数据,这就叫跨域。

    2.知识剖析

    常见的跨域方法有:

    1. jsonp,利用了src属性可以跨域的特性
    2. document.domain跨子域
    3. Access Control,服务器端发送Access-Control-Allow-Origin响应头,规定请求的域名的访问权限
    4. nginx反向代理,客户端nginx拦截代码中虚假的http请求,替换成正确的http

    如何算不同的域?

    1. 不同域名
    2. 同一域名,不同端口
    3. 同一域名,不同协议
    4. 域名和域名对应ip
    5. 主域相同,子域不同
    6. 同一域名,不同二级域名

    3.常见问题

    jsonp是如何实现跨域的

    4.解决方案

    有两个文件处于不同域中:

    A.html
    <script type="text/javascript">
       //回调函数
       function callback(data) {
           alert(data.message);
       }
    </script>
    <script type = "text/javascript" src ="http://localhost:20002/B.js"></script>
    
    B.js
    //调用callback函数,并以json数据形式作为阐述传递,完成回调
    callback({message: "success"});
    

    结果会alert“success”,这就是jsop的基本原理

    5.编码实战

    客户端:

    <script>
       //显示后台返回数据的一个属性
       function jsonp(data) {
           //alert传入的data数组项中的一个属性
           alert(JSON.parse(data)[0].location);
       }
    
       //添加<script>标签的方法
       function addScriptTag(src) {
           var script = document.createElement('script');
           script.setAttribute("type", "text/javascript");
           script.src = src;
           document.body.appendChild(script);
       }
    
       //防止script标签放在头部运行时,body还未渲染
       window.onload = function () {
           //将数据从url中提取出来,便于添加数据。
           var name = "冯强", age = 24, callback = "jsonp";
           addScriptTag("http://59.110.174.154/test/test1.js?name=" + name + "&age=" + age + "&callback=" + callback);
       }
    
    </script>
    

    服务器端:

    //定义一些变量
    var name,age,callback,data=[];
    //遍历script标签
    [].forEach.call(document.scripts, function (val, index, arr) {
       if (val.src) {
           //使用正则表达式匹配url字符串,并在回调函数中将我们需要的参数传递给变量
           decodeURI(val.src).replace(/.*\?name=(.*)&age=(.*)&callback=(.*)/g, function (match, p1, p2,p3,offset,string) {
               name=p1;
               age=p2;
               callback=p3;
           });
       }
    });
    
    //数据库的一段JSON代码
    var json=[
       {"name":"小宇","age":"24","location":"襄阳"},
    {"name":"恒光","age":"24","location":"益阳"},
    {"name":"冯强","age":"24","location":"黄冈"}
    ]
    
    //遍历json,查询符合参数的项,屏添加到data数组中
    json.forEach(function(val,index,arr){
       if(val.name===name&&val.age===age){
           data.push(json[index]);
       }
    })
    
    //JSON化data数组
    data=JSON.stringify(data);
    
    //使用eval解析callback函数名,并传入data参数,执行函数
    eval(callback)(data);
    

    6.扩展思考

    jsonp跨域有什么优缺点?

    优点:兼容性很好好,可以在古老的浏览器中运行,
    缺点:它只支持GET请求而不支持POST等其它类型的HTTP请求。

    jsonp和ajax有什么关系?

    ajax是通过操作XMLHttpRequest对象发送请求,获取返回的数据。JSONP的全称为JSON
    with Padding,Padding指的就是包裹在JSON外层的回调函数。从刚才的例子中,咱们发现JSONP并没有操作XMLHttpRequest,因此jsonp和ajax没有任何关系。

    如何用jQuery实现JSONP

    前端代码:
    $.ajax({
       url: "http://tonghuashuo.github.io/test/jsonp.txt",
    dataType: 'jsonp',
    jsonp: "callback",
    jsonpCallback: "dosomething"
    })
       .done(function (res) {
           console.log("success");
           console.log(res);
       })
       .fail(function (res) {
           console.log("error");
           console.log(res);
       });
    
    这里使用了ajax这个方法,但实际上jsonp和ajax没有任何关系,只是因为jsonp请求和ajax请求相似,jquery在这里有误导之嫌。
    

    7.参考文献

    参考一:跨域资源共享CORS详解
    参考二:5分钟彻底明白JSONP
    参考三:深入浅出JSONP--解决ajax跨域问题

    相关文章

      网友评论

        本文标题:跨域解决方案之jsonp

        本文链接:https://www.haomeiwen.com/subject/qxgxdxtx.html