• js便签笔记(13)——jsonp事实上非常easy【ajax跨域请求】


    前两天被问到ajax跨域怎样解决,还真被问住了,光知道有个什么jsonp,迷迷糊糊的没有说上来。抱着有问题必须解决的态度,我看了很多资料,原来如此。。

    为何一直知道jsonp,但一直迷迷糊糊的不明确呢?——网上那些介绍资料都写的太复杂了!

    我是能多简单就多简单,争取让你十分钟看完!

    1. 同源策略

    ajax之所以须要“跨域”。罪魁祸首就是浏览器的同源策略。即,一个页面的ajax仅仅能获取这个页面同样源或者同样域的数据

    怎样叫“同源”或者“同域”呢?——协议、域名、port号都必须同样。比如:

    http://google.com  和  https://google.com 不同。由于协议不同;

    http://localhost:8080  和  http://localhost:1000 不同。由于port不同。

    http://localhost:8080  和  https://google.com 不同,协议、域名、port号都不同,根本不是一家的。

    依据同源策略,我自己做的一个网页 http://localhost:8080/test.html 就无法通过ajax直接获取 http://google.com 的数据。

    比如,我用ajax去訪问一个不同域的页面。错误结果是这种:

     

    大家想想。这样事实上也有道理。假设没有同源策略,你我都能够随便通过ajax直接获取其它站点的信息,这还不乱套了。

    。。我自己做一个搜索界面,搜索时直接用ajax从百度获取数据,那不成了小偷了。

    可是跨域訪问是少不了的,mail.163.com 的网页可能须要从 news.163.com 域下获取新闻信息。那怎么办?——開始咱们的跨域之旅(当然用iframe也能够实现)

    2. 从“盗链”说起

    互联网的很多站点之间图片相互盗链。A站点网页的img.src直接链接到B站点的图片地址,这是常有的事儿。说到“盗链”。大家第一想到的可能是怎样去防止盗链,今儿咱无论那个。

    你再想想“盗链”和“同源策略”这两个词之间有什么关系?——对,矛盾!既然都“同源策略”了。怎么还能“盗链”呢?

    世间万物都有矛盾,有矛盾了照样能够和谐共处。并不一定非要你死我活。

    重点:<img>的src(获取图片),<link>的href(获取css)。<script>的src(获取javascript)这三个都不符合同源策略。它们能够跨域获取数据。

    因此,你能够直接从一些cdn上获取jQuery。而且你站点上的图片也随时可能被别人盗用,全部最好加上水印!

    而我们今天的主角——jsonp——就是由于<script>的src不符合同源策略而来的

    3. JSONP

    比如,域名 a.com 下有一个 a.com/test.html 网页。域名 b.com 下有一个 b.com/data.html 网页和 b.com/alert.js 文件。

    引导第一步:简单引用js

    编写 b.com/alert.js 例如以下:

    alert(123);

    对 a.com/test.html 编写例如以下代码:

    <script type='text/javascript' src='http://b.com/alert.js'/>

    执行 a.com/test.html,结果非常明显。就是弹出 【123】 。

     

    引导第二步:引用js返回数据

    将 b.com/alert.js 改动为:

    myFn(100);

    将 a.com/test.html 改动为:

    <script>
        function myFn ( data ) {
            alert( data + 'px' );
        }
    </script>
    <script type='text/javascript' src='http://b.com/alert.js'/>

    执行 a.com/test.html,结果是弹出【 100px 】,这个应该也没有什么疑问。

     

    引导第三步:已经跨域成功!

    第二步中。假设data——即100——是我要跨域在b.com下获取的一个数据,那么咱们这不就是已经实现跨域请求了吗。!

    把这个过程再清晰的捋一遍:

    • <script>的src不符合同源策略;
    • 我通过给<script>的src赋值一个跨域的文件的网址(可能不是一个js文件),这个文件返回的字符串,浏览器会当作javascript来解析;
    • 而这段javascript中。就能够包括着我所须要的跨域server端的数据;
    • 最后,我在本页面定义一个myFn函数用来展示数据,而这段javascript中就能够直接调用myFn函数。

     

    引导第四步:引用html格式

    <script>的src不一定只指向javascript文件,能够指向不论什么地址。

    比如:

    将 a.com/test.html 改动为:

    <script>
        function myFn ( data ) {
            alert( data + 'px' );
        }
    </script>
    <script type='text/javascript' src='http://b.com/data.html'/>

    将 b.com/data.html 编写为:(注意,data.html中就写下面一行代码,多了不写)

    myFn(100); 

    执行 a.com/test.html 。结果依旧是【 100px 】

    当中。“100”就是我们要跨域请求的数据。

     

    引导第五步:动态数据

    假设要请求的数据是动态的。那就要在动态页面中编写。

    那么我们就让 a.com/test.html 去调用一个动态的aspx页面:

    <script>
        function myFn ( data ) {
            alert( data + 'px' );
        }
    </script>
    <script type='text/javascript' src='http://b.com/data.aspx?callback=myFn'/>

    大家注意,我们在 src 地址中添加了“?

    callback=myFn”,意思是把显示数据的函数也动态传过去了,而第二步、第四步都是静态的写在被调用的文件里的。

    至于callback參数后台怎样接收。怎样使用,请接着看:

    在 b.com 下添加一个 b.com/data.aspx 页面。后台代码例如以下:

        protected void Page_Load(object sender, EventArgs e)
        {
            if (this.IsPostBack == false)
            {
                string callback = "";
                if (Request["callback"] != null)
                {
                    callback = Request["callback"];
    
                    //server端要返回的数据
                    string data = "1024";
    
                    Response.Write(callback + "(" + data + ")");
                }
            }
        }

    代码非常easy。获取callback參数,然后组成一个函数的形式返回。假设“b.com/data.aspx?

    callback=myFn”调用的话,那么返回的就是" myFn(1024) "。

    返回的数据变成动态的了(“1024”),前端页面用于显示数据的函数也编程了动态的了(“callback=myFn”),可是归根结底,形式还是一样的。

     

    引导第六步:调用封装

    a.com/test.html 中,唯独一个<script>静静的躺在那里,运行一次之后,就没有作用了。

    而实际情况是。a.com/test.html 中,可能随着用户的操作发生若干次的调用。怎么办?——动态添加呗。

    function addScriptTag(src) {
        var script = document.createElement("script");
        script.setAttribute("type", "text/javascript");
        script.src = src;
        document.body.appendChild(script);
    }
    
    function myFn (data) {
        alert(data + 'px');  
    }
    
    //须要调用时:
    //addScriptTag('b.com/data.aspx?callback=myFn');

     

    4. 总结

    以上层层描写叙述的就是JSONP。你不必去记住它的定义,看明确了上述文字。就全能理解。

    重点在于:同源策略 + <script>的src不属于同源策略 + 通过<script>的src指向的文件返回server端数据

    ok,就这些!

    -------------------------------------------------------------------------------------------------------------

    欢迎关注我的微博

    也欢迎关注我的其它教程:

    从设计到模式深入理解javascript原型和闭包系列微软petshop4.0源代码解读视频》《json2.js源代码解读视频

  • 相关阅读:
    android 线程的优先级设置方法
    android插件开发
    针对AsyncTask的分析
    针对平板的扩展
    adb shell dumpsys activity
    gzip相关【转帖】
    android中也需要SQL语句
    monkey脚本
    eclipse 引入外部包不能运行 NoClassDefFoundError 的问题
    翻译 : fragment
  • 原文地址:https://www.cnblogs.com/mengfanrong/p/5085889.html
Copyright © 2020-2023  润新知