精华内容
下载资源
问答
  • jsonp跨域原理解析

    万次阅读 多人点赞 2018-09-01 19:25:07
    由于浏览器同源策略的限制,非同源下的请求,都会产生跨域问题,jsonp即是为了解决这个问题出现的一种简便解决方案。 同源策略即:同一协议,同一域名,同一端口号。当其中一个不满足时,我们的请求即会发生跨域...

    背景:

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

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

    举个简单的例子:

    1. http://www.abc.com:3000到https://www.abc.com:3000的请求会出现跨域(域名、端口相同但协议不同)
    2. http://www.abc.com:3000到http://www.abc.com:3001的请求会出现跨域(域名、协议相同但端口不同)
    3. 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上的静态资源举例:

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

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

    JSONP跨域实现:

    根据上边所说的,我们要用过利用srcipt标签的src属性来实现,那么我们如何做呢,我们来看一段简单的代码,为了方便,我这里使用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指向的地址,注意:这里必须使用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 + ')');
    });

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

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

    总结:

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

    展开全文
  • JSONP跨域原理

    2019-12-17 21:06:35
    JSONP跨域原理: ​ 利用了src不受同源策略的影响 ,可以访问其他页面的数据。 源生JS实现JSONP的步骤: 客户端 定义获取数据后调用的回调函数 动态生成对服务端JS进行引用的代码 设置url为提供jsonp服务的url地址...

    JSONP跨域相关问题

    问题起源:

    ​ 由于同源策略,AJAX直接请求非同源数据接口存在跨域无权限访问的问题。

    JSONP跨域原理:

    ​ 利用了src不受同源策略的影响 ,可以访问非同源的数据。

    源生JS实现JSONP的步骤:

    客户端
    1. 定义获取数据后调用的回调函数
    2. 动态生成对服务端JS进行引用的代码
      • 设置url为提供jsonp服务的url地址,并在该url中设置相关callback参数
      • 创建script标签,并设置其src属性
      • script标签加入head,此时调用开始。
    服务端

    将客户端发送的callback参数作为函数名来包裹住JSON数据,返回数据至客户端。

    AJAX与JSONP的异同:

    1. AJAXJSONP这两种技术在调用方式上“看起来”很像,目的也一样,都是请求一个url,然后把服务器返回的数据进行处理,因此jQueryextjs等框架都把JSONP作为AJAX的一种形式进行了封装;
    2. AJAXJSONP其实本质上是不同的东西。AJAX的核心是通过XmlHttpRequest获取非本页内容,而JSONP的核心则是动态添加script标签来调用服务器提供的js脚本。
    3. 所以说,其实AJAXJSONP区别不在于是否跨域,AJAX通过服务端代理一样可以实现跨域,JSONP本身也不排斥同域的数据的获取。
    4. 还有就是,JSONP是一种方式或者说非强制性协议,如同AJAX一样,它也不一定非要用JSON格式来传递数据,如果你愿意,字符串都行,只不过这样不利于用JSONP提供公开服务。
    5. 总而言之,JSONP不是AJAX的一个特例,哪怕jQuery等巨头把它封装进了AJAX,也不能改变这一点!

    最后,

    JSONP跨域只支持get方式的跨域,post是不支持的。
    一个JSONP跨域的例子

    展开全文
  • jsonp跨域原理

    2017-05-31 15:48:00
    在项目中遇到一个jsonp跨域的问题,于是仔细的研究了一番jsonp跨域原理。搞明白了一些以前不是很懂的地方,比如: 1)jsonp跨域只能是get请求,而不能是post请求; 2)jsonp跨域原理到底是什么; 3)除了jsonp...

    在项目中遇到一个jsonp跨域的问题,于是仔细的研究了一番jsonp跨域的原理。搞明白了一些以前不是很懂的地方,比如:

    1)jsonp跨域只能是get请求,而不能是post请求;

    2)jsonp跨域的原理到底是什么;

    3)除了jsonp跨域之外还有那些方法绕过“同源策略”,实现跨域访问;

    4)jsonp和ajax,或者说jsonp和XMLHttpRequest是什么关系;

       虽然 jsonp 的实现跟 ajax 没有半毛钱关系jsonp是通过 script的src实现的(具体看后面的解析),但是最终目的都是向服务器请求数据然后回调,而且为了方便,所以      jQuery把 jsonp 也封装在了 $.ajax 方法中,调用方式与 ajax 调用方式略有区别。

    等等。

    1.同源策略

    说到跨域,首先要明白“同源策略”。同源是指:js脚本只能访问或者请求相同协议相同域名(网址/ip),相同端口的页面。

    我们知道,js脚本可以访问所在页面的所有元素。通过ajax技术,js也可以访问同一协议,同一个domain(ip),同一端口的服务器上的其他页面,请求到浏览器端之后,利用js就可以进行任意的访问。但是对于协议不同, 或者domain不同或者端口不同的服务器上的页面就无能为力了,完全不能进行请求。

    下面在本地搭建两个tomcat,分别将端口设为8080,和8888,进行相关实验。显然他们的端口是不同的。演示如下:

    http://localhost:8888/html4/ajax.html的代码如下:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    <!doctype html>
    <html>
    <head>
        <meta charset="utf-8">
        <meta name="keywords" content="jsonp">
        <meta name="description" content="jsonp">
        <title>jsonp</title>
        <style type="text/css">
            *{margin:0;padding:0;}
            a{display:inline-block;margin:50px 50px;}
        </style>
    </head>
    <body>
        <a href="javascript:;" onclick="myAjax();">click me</a>
         
    <script type="text/javascript" src="js/jquery-1.11.1.min.js"></script>
    <script type="text/javascript">
    function myAjax(){
        var xmlhttp;
        if(window.XMLHttpRequest){
            xmlhttp = new XMLHttpRequest();
        }else{
            xmlhttp = ActionXObject("Microsoft.XMLHTTP");
        }
         
        xmlhttp.onreadystatechange = function(){
            if (xmlhttp.readyState==4 && xmlhttp.status==200){
                console.log(xmlhttp.responseText);         
            }
        }
        var url = "http://localhost:8080/minisns/json.jsp" + "?r=" + Math.random();
        xmlhttp.open("Get", url, true);
        xmlhttp.setRequestHeader("Content-type","application/x-www-form-urlencoded");
     
        xmlhttp.send();
    }
     
    </script>
    </body>
    </html>

    这里为了结果不受其他js库的干扰,使用了原生的XMLHttpRequest来处理,结果如下:

    我们看到8080端口的js的ajax请求无法访问8888端口的页面。原因是“同源策略不允许读取”。

    既然普通的ajax不能访问,那么怎样才能访问呢?大家都知道,使用jsonp啊,那jsonp的原理是什么呢?他为什么能跨域呢?

    2.jsonp跨域的原理

    我们知道,在页面上有三种资源是可以与页面本身不同源的。它们是:js脚本,css样式文件,图片,像taobao等大型网站,很定会将这些静态资源放入cdn中,然后在页面上连接,如下所示,所以它们是可以链接访问到不同源的资源的。

    1)<script type="text/javascript" src="某个cdn地址" ></script>

    2)<link type="text/css" rel="stylesheet" href="某个cdn地址" />

    3)<img src="某个cdn地址" alt=""/>

    而jsonp就是利用了<script>标签可以链接到不同源的js脚本,来到达跨域目的。当链接的资源到达浏览器时,浏览器会根据他们的类型来采取不同的处理方式,比如,如果是css文件,则会进行对页面 repaint,如果是img 则会将图片渲染出来,如果是script 脚本,则会进行执行,比如我们在页面引入了jquery库,为什么就可以使用 $ 了呢?就是因为 jquery 库被浏览器执行之后,会给全局对象window增加一个属性: $ ,所以我们才能使用 $ 来进行各种处理。(另外为什么要一般要加css放在头部,而js脚本放在body尾部呢,就是为了减少repaint的次数,另外因为js引擎是单线程执行,如果将js脚本放在头部,那么在js引擎在执行js代码时,会造成页面暂停。)

    利用 页面上 script 标签可以跨域,并且其 src 指定的js脚本到达浏览器会执行的特性,我们可以进行跨域取得数据。我们用一个例子来说明:

    (1)访问js

     

    8888端口的html4项目中的jsonp.html页面代码如下:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    <!doctype html>
    <html>
    <head>
        <meta charset="utf-8">
        <meta name="keywords" content="jsonp">
        <meta name="description" content="jsonp">
        <title>jsonp</title>
    </head>
    <body>
     
    <script type="text/javascript" src="js/jquery-1.11.1.js"></script>
    <script type="text/javascript">
    var url = "http://localhost:8080/html5/jsonp_data.js";
    // 创建script标签,设置其属性
    var script = document.createElement('script');
    script.setAttribute('src', url);
    // 把script标签加入head,此时调用开始
    document.getElementsByTagName('head')[0].appendChild(script);
    function callbackFun(data)
    {
        console.log(data.age);
        console.log(data.name);
    }  
    </script>
    </body>
    </html>

     其访问的8080端口的html5项目中的jsonp_data.js代码如下:

    1
    callbackFun({"age":100,"name":"yuanfang"})

     将两个tomcate启动,用浏览器访问8888端口的html4项目中的jsonp.html,结果如下:

    上面我们看到,我们从8888 端口的页面通过 script 标签成功 的访问到了8080 端口下的jsonp_data.js中的数据。这就是 jsonp 的基本原理,利用script标签的特性,将数据使用json格式用一个函数包裹起来,然后在进行访问的页面中定义一个相同函数名的函数,因为 script 标签src引用的js脚本到达浏览器时会执行,而我们有定义了一个同名的函数,所以json格式的数据,就做完参数传递给了我们定义的同名函数了。这样就完成了跨域数据交换。jsonp的含义是:json with padding,而在json数据外包裹它的那个函数,就是所谓的 padding 啦^--^

     

    (2)访问servlet---比较实用的例子

    8080端口的html5项目中定义一个servlet:

    复制代码
    package com.tz.servlet;
    
    import java.io.IOException;
    import javax.servlet.ServletException;
    import javax.servlet.annotation.WebServlet;
    import javax.servlet.http.HttpServlet;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    import com.alibaba.fastjson.JSON;
    
    @WebServlet("/JsonServlet")
    public class JsonServlet extends HttpServlet 
    {
        private static final long serialVersionUID = 4335775212856826743L;
    
        protected void doPost(HttpServletRequest request, HttpServletResponse response) 
                throws ServletException, IOException 
        {
            String callbackfun = request.getParameter("mycallback");
            System.out.println(callbackfun);    // callbackFun
            response.setContentType("text/json;charset=utf-8");
            
            User user = new User();
            user.setName("yuanfang");
            user.setAge(100);
            Object obj = JSON.toJSON(user);
            
            System.out.println(user);            // com.tz.servlet.User@164ff87
            System.out.println(obj);            // {"age":100,"name":"yuanfang"}
            callbackfun += "(" + obj + ")";    
            System.out.println(callbackfun);    // callbackFun({"age":100,"name":"yuanfang"})
            
            response.getWriter().println(callbackfun);
        }
    
        protected void doGet(HttpServletRequest request, HttpServletResponse response) 
                throws ServletException, IOException 
        {
            this.doPost(request, response);
        }
    
    }
    复制代码

     

     在8888端口的html4项目中的jsonp.html来如下的跨域访问他:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    <!doctype html>
    <html>
    <head>
        <meta charset="utf-8">
        <meta name="keywords" content="jsonp">
        <meta name="description" content="jsonp">
        <title>jsonp</title>
        <style type="text/css">
            *{margin:0;padding:0;}
            div{width:600px;height:100px;margin:20px auto;}
        </style>
    </head>
    <body>
        <div>
            <a href="javascript:;">jsonp测试</a>
        </div>
         
    <script type="text/javascript" src="js/jquery-1.11.1.js"></script>
    <script type="text/javascript">
    function callbackFun(data)
    {
        console.log(111);
        console.log(data.name);
        //data.age = 10000000;
        //alert(0000);
    }
    $(function(){
        $("a").on("click", function(){     
            $.ajax({
                type:"post",
                url:"http://localhost:8080/html5/JsonServlet",
                dataType:'jsonp',
                jsonp:'mycallback',
                jsonpCallback:'callbackFun',
                success:function(data) {
                    console.log(2222);
                    console.log(data.age);
                }
            });
        })
    });
    </script>
    </body>
    </html>

     结果如下:

    我们看到,我们成功的跨域取到了servlet中的数据,而且在我们指定的回调函数jsonpCallback:'callbackFun' 和 sucess 指定的回调函数中都进行了执行。而且总是callbackFun先执行,如果我们打开注释://data.age = 10000000; //alert(0000);

    就会发现:在callbackFun中对 data 进行修改之后,success指定的回调函数的结果也会发生变化,而且通过alert(0000),我们确定了如果alert(000)没有执行完,success指定的函数就不会开始执行,就是说两个回调函数是先后同步执行的。

    结果如下:

    3.jsonp 跨域与 ajax  

    从上面的介绍和例子,我们知道了 jsonp 跨域的原理,是利用了script标签的特性来进行的,但是这和ajax有什么关系呢?显然script标签加载js脚本和ajax一点关系都没有,在没有ajax技术之前,script标签就存在了的。只不过是jquery的封装,使用了ajax来向服务器传递 jsonp 和 jsonpCallback 这两个参数而已。如果我们再服务器端和客户端,对参数 jsonp 和 jsonpCallback 的值,协调好(也就是一致性),那么就没有必要使用ajax来传递着两个参数了,就像上面第二个例子那样,直接构造一个script标签就行了。不过实际上,我们还是会使用ajax的封装,因为它在调用完成之后,又将动态添加的script标签去掉了,我们看下相关的源码:

     

    上面的代码先构造一个script标签,然后注册一个onload的回调,最后将构造好的script标签insert进去。insert完成之后,会触发onload回调,其中又将前面插入的script标签去掉了。其中的 代码 callback( 200, "success" ) 其实就是触发 ajax 的jsonp成功时的success回调函数,callback函数其实是一个 done 函数,其中包含了下面的代码:

     

    因为传入的是 200 ,所以 isSuccess = true; 所以执行 "success"中的回调函数,response = ajaxHandleResponse(...) 就是我们处理服务器servelt返回的数据,我们可以调试:console.log(response.data.age); console.log(response.data.name); 看到结果。

    3.jsonp 跨域与 get/post 

    我们知道 script,link, img 等等标签引入外部资源,都是 get 请求的,那么就决定了 jsonp 一定是 get 的,那么为什么我们上面的代码中使用的 post 请求也成功了呢?这是因为当我们指定dataType:'jsonp',不论你指定:type:"post" 或者type:"get",其实质上进行的都是 get 请求!!!从两个方面可以证明这一点:

    1)如果我们将JsonServlet中的 doGet()方法注释掉,那么上面的跨域访问就不能进行,或者在 doPost() 和 doGet() 方法中进行调试,都可以证明这一点;

    2)我们看下firebug中的“网络”选项卡:

    我们看到,即使我们指定 type:"post",当dataType:"jsonp" 时,进行的也是 GET请求,而不是post请求,也就是说jsonp时,type参数始终是"get",而不论我们指定他的值是什么,jquery在里面将它设定为了get. 我们甚至可以将 type 参数注释掉,都可以跨域成功:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    $(function(){
        $("a").on("click"function(){     
            $.ajax({
                //type:"post",
                url:"http://localhost:8080/html5/JsonServlet",
                dataType:'jsonp',
                jsonp:'mycallback',
                jsonpCallback:'callbackFun',
                success:function(data) {
                    console.log(2222);
                    console.log(data.age);
                }
            });
        })
    });

     

    所以jsonp跨域只能是get,jquery在封装jsonp跨域时,不论我们指定的是get还是post,他统一换成了get请求,估计这样可以减少错误吧。其对应的query源码如下所示:

    复制代码
    // Handle cache's special case and global
    jQuery.ajaxPrefilter( "script", function( s ) {
        if ( s.cache === undefined ) {
            s.cache = false;
        }
        if ( s.crossDomain ) {
            s.type = "GET";
            s.global = false;
        }
    });
    复制代码

    if( s.crossDomain){ s.type = "GET"; ...} 这里就是真相!!!!!!!!在ajax的过滤函数中,只要是跨域,jquery就将其type设置成"GET",真是那句话:在源码面前,一切了无秘密!jquery源码我自己很多地方读不懂,但是并不妨碍我们去读,去探索!

     

    4.除了jsonp跨域方法之外的其他跨域方法

    其实除了jsonp跨域之外,还有其他方法绕过同源策略,

    1)因为同源策略是针对客户端的,在服务器端没有什么同源策略,是可以随便访问的,所以我们可以通过下面的方法绕过客户端的同源策略的限制:客户端先访问 同源的服务端代码,该同源的服务端代码,使用httpclient等方法,再去访问不同源的 服务端代码,然后将结果返回给客户端,这样就间接实现了跨域。相关例子,参见博文:http://www.cnblogs.com/digdeep/p/4198643.html

    2)在服务端开启cors也可以支持浏览器的跨域访问。cors即:Cross-Origin Resource Sharing 跨域资源共享。jsonp和cors的区别是jsonp几乎所有浏览器都支持,但是只能是get,而cors有些老浏览器不支持,但是get/post都支持,cors的支持情况,可以参见下图(来自:http://caniuse.com/#search=cors)

    cors实例:

    项目html5中的Cors servlet:

    复制代码
    public class Cors extends HttpServlet 
    {
        private static final long serialVersionUID = 1L;
           
    
        protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException 
        {
            response.setHeader("Access-Control-Allow-Origin", "*");
            response.setHeader("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS");
            response.setHeader("Access-Control-Allow-Headers", "Content-Type");
            response.getWriter().write("cors get");
        }
    
        protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
        {
            response.setHeader("Access-Control-Allow-Origin", "*");
            response.setHeader("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS");
            response.setHeader("Access-Control-Allow-Headers", "Content-Type");
            response.getWriter().write("cors post");
        }
    
    }
    复制代码

    在html4项目中访问他:

    复制代码
    <!doctype html>
    <html>
    <head>
        <meta charset="utf-8">
        <meta name="keywords" content="jsonp">
        <meta name="description" content="jsonp">
        <title>cors</title>
        <style type="text/css">
            *{margin:0;padding:0;}
            div{width:600px;height:100px;margin:20px auto;}
        </style>
    </head>
    <body>
        <div>
            <a href="javascript:;">cors测试</a>
        </div>
        
    <script type="text/javascript" src="js/jquery-1.11.1.js"></script>
    <script type="text/javascript">
    $(function(){
        $("a").on("click", function(){        
            $.ajax({
                type:"post",
                url:"http://localhost:8080/html5/cors",
                success:function(data) {
                    console.log(data);
                    alert(data);
                }
            });
        })
    });    
    </script>
    </body>
    </html>
    复制代码

    访问结果如下:

    5. 参数jsonp 和 jsonpCallback

    jsonp指定使用哪个名字将回调函数传给服务端,也就是在服务端通过 request.getParameter(""); 的那个名字,而jsonpCallback就是request.getParamete("")取得的值,也就是回调函数的名称。其实这两个参数都可以不指定,只要我们是通过 success : 来指定回调函数的情况下,就可以省略这两个参数,jsnop如果不知道,默认是 "callback",jsnpCallback不指定,是jquery自动生成的一个函数名称,其对应源码如下:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    var oldCallbacks = [],
        rjsonp = /(=)\?(?=&|$)|\?\?/;
     
    // Default jsonp settings
    jQuery.ajaxSetup({
        jsonp: "callback",
        jsonpCallback: function() {
            var callback = oldCallbacks.pop() || ( jQuery.expando + "_" + ( nonce++ ) );
            this[ callback ] = true;
            return callback;
        }
    });

     

    展开全文
  • JSONP 跨域原理

    2020-12-17 11:06:52
    同源策略: 为保护用户信息安全,防止恶意网站窃取用户数据,浏览器限制本域中的脚本只能访问本域中...JSONP 核心原理 script 标签不受同源策略影响。 动态插入到 DOM 中的 script 脚本可以立即得到执行。 实现步骤 .

    同源策略 & 跨域

    什么是 JSONP?

    JSONPJSON with Padding)是资料格式JSON的一种“使用模式”,可以让网页从别的网域获取资料。 —— 维基百科

    JSONP 核心原理

    • script 标签不受同源策略影响。
    • 动态插入到 DOM 中的 script 脚本可以立即得到执行。

    实现步骤

    1. 客户端创建一个 JavaScript 函数,用来接收服务端返回的数据。
    function onResponse(data) {
        // do something
    }
    
    1. 客户端动态插入 script 标签执行请求。
    var script = document.createElement('script')
    script.src = 'protocal://domain:port/path?callback=onResponse'
    document.head.appendChild(script)
    document.head.removeChild(script)
    
    1. 服务端将数据和 js 回调函数名拼接为函数调用的字符串并返回给客户端。
    app.get('/path', function(request, response) {
        var data = getData()
        var callback = request.query.callback
        var result = `${callback}(${JSON.stringify(data)});`
        response.send(result)
    })
    
    1. 客户端接收到 script 标签响应并自动执行回调函数。

    JSONP 的缺点

    • 只能使用 GET 请求。
    • 动态插入的 script 脚本可能被注入恶意代码。
    展开全文
  • Jsonp跨域原理

    2019-10-13 23:23:06
    callback这个参数,callback参数就是核心所在。首先我们知道,这个get请求已经被发出去了,那么我们如何接口请求回来的数据呢,callback=func...其实jsonp的整个过程就类似于前端声明好一个函数,后端返回执行函数。
  • jQuery jsonp跨域原理

    2018-03-07 15:59:35
    实际上单jQuery还是实现不了跨域加载数据的,由于XMLHttpRequest的安全设置,是不允许直接跨域的。... jQuery jsonp跨域原理实际就是使用script标签加载配置对象中的跨域url,再使用script标签加载之前,会在客...
  • 在项目中遇到一个jsonp跨域的问题,于是仔细的研究了一番jsonp跨域原理。搞明白了一些以前不是很懂的地方,比如: 1)jsonp跨域只能是get请求,而不能是post请求; 2)jsonp跨域原理到底是什么; 3)除了...
  • 在项目中遇到一个jsonp跨域的问题,于是仔细的研究了一番jsonp跨域原理。搞明白了一些以前不是很懂的地方,比如: 1)jsonp跨域只能是get请求,而不能是post请求; 2)jsonp跨域原理到底是什么; 3)...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 2,351
精华内容 940
关键字:

jsonp跨域原理