zoukankan      html  css  js  c++  java
  • jsonp跨域问题

      JSONP是一个非官方的协议,它允许在服务器端集成Script tags返回至客户端,通过javascript callback的形式实现跨域访问(这仅仅是JSONP简单的实现形式)。

    同源策略限制

      同源策略限制:出于安全方面的考虑,浏览器阻止代码获得或者更改从另一个域名下获得的文件或者信息。也就是说我们的请求地址必须和当前网站的地指相同。同源策略通过隔离来实现对资源的保护。这个策略的历史非常悠久从Netscape Navigator 2.0时代就开始了。

    什么是跨域?

    简单的来说,页面中的JavaScript无法访问其他服务器上的数据,即“同源策略”。而跨域就是通过某些手段来绕过同源策略限制,实现不同服务器之间通信的效果。

    JSONP跨域的原理

    在同源策略下,在某个服务器下的页面是无法获取到该服务器以外的数据的,但img、iframe、script等标签是个例外,这些标签可以通过src属性请求到其他服务器上的数据。利用script标签的开放策略,我们可以实现跨域请求数据,当然,也需要服务端的配合。当我们正常地请求一个JSON数据的时候,服务端返回的是一串JSON类型的数据,而我们使用JSONP模式来请求数据的时候,服务端返回的是一段可执行的JavaScript代码。

    具体流程如下:

    1. 首先在客户端注册一个callback, 然后把callback的名字传给服务器。
    
    2. 此时,服务器先生成 json 数据,然后以 javascript 语法的方式,生成一个function , function 名字就是传递上来的参数 jsonp,最后将 json 数据直接以入参的方式,放置到 function 中,这样就生成了一段 js 语法的文档,返回给客户端。
    3. 客户端浏览器,解析script标签,并执行返回的 javascript 文档,此时数据作为参数,传入到了客户端预先定义好的 callback 函数里.(动态执行回调函数)

     举个例子,假如需要从服务器(http://www.a.com/user?id=123)获取的数据如下:

    {"id": 123, "name" : 张三, "age": 17}

    那么,使用JSONP方式请求(http://www.a.com/user?id=123?callback=foo)的数据将会是如下: 

    foo({"id": 123, "name" : 张三, "age": 17});

    当然,如果服务端考虑得更加充分,返回的数据可能如下: 

    try{foo({"id": 123, "name" : 张三, "age": 17});}catch(e){}

    这时候我们只要定义一个foo()函数,并动态地创建一个script标签,使其的src属性为http://www.a.com/user?id=123?callback=foo: 

    function executeJsonp(url){
      var eleScript= document.createElement("script");
      eleScript.type = "text/javascript";
      eleScript.src = url;
      document.getElementsByTagName("head")[0].appendChild(eleScript);
    }
    
    function foo(data){
        for(var p in data){
          console.log(data[p]);
        }
    }
    
    var url = "http://www.a.com/user?id=123?callback=foo";
    executeJsonp(url)

    在jQuery中如何通过JSONP来跨域获取数据

    第一种方法是在ajax函数中设置dataType为'jsonp': 

    $.ajax({
            dataType: 'jsonp',
            url: 'http://www.a.com/user?id=123',
            success: function(data){
                    //处理data数据
            }
    });
    getJsonp: function(url, param, callback) {
            $.ajax({
                url: url,
                data: param,
                dataType: "jsonp",
                success: callback,
                error: function(data){
                    alert('网络异常,请稍后再试!');
                }
            })
        }

    第二种方法是利用getJSON来实现,只要在地址中加上callback=?参数即可: 

    $.getJSON('http://www.a.com/user?id=123&callback=?', function(data){
            //处理data数据
    });

    也可以简单地使用getScript方法:

    /此时也可以在函数外定义foo方法
    function foo(data){
            //处理data数据
    }
    $.getJSON('http://www.a.com/user?id=123&callback=foo');

    JSONP的优点是:它不像XMLHttpRequest对象实现的Ajax请求那样受到同源策略的限制;它的兼容性更好,在更加古老的浏览器中都可以运行,不需要XMLHttpRequest或ActiveX的支持;并且在请求完毕后可以通过调用callback的方式回传结果。

    JSONP的缺点则是:它只支持GET请求而不支持POST等其它类型的HTTP请求;它只支持跨域HTTP请求这种情况,不能解决不同域的两个页面之间如何进行JavaScript调用的问题。

  • 相关阅读:
    zookeeper常用命令
    linux查看日志相关命令
    第三十一期: VueRouter源码浅析 传统前端和多媒体前端
    第二十八期:模型,模块,组件,框架和架构
    星际2光速注卵
    星际心得
    英语词根研究和单词记忆
    星际2如何离线模式打电脑和rpg地图练操作
    星际研究
    第一篇帖子:不利用中间变量交换两个数字的小算法题
  • 原文地址:https://www.cnblogs.com/v10258/p/3383796.html
Copyright © 2011-2022 走看看