zoukankan      html  css  js  c++  java
  • 【前端】直击源头的让你3秒理解并且会用Jsonp!!!

    1. 同源策略

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

    如何叫“同源”或者“同域”呢?——协议、域名、端口号都必须相同。例如:

    不同,因为协议不同;

    不同,因为端口不同;

    不同,协议、域名、端口号都不同,根本不是一家的。

    根据同源策略,我自己做的一个网页 就无法通过ajax直接获取 的数据。

    例如,我用ajax去访问一个不同域的页面,错误结果是这样的:

    大家想想,这样其实也有道理。如果没有同源策略,你我都可以随便通过ajax直接获取其他网站的信息,这还不乱套了。。。我自己做一个搜索界面,搜索时直接用ajax从百度获取数据,那不成了小偷了。。。

    但是跨域访问是少不了的, 的网页可能需要从 域下获取新闻信息,那怎么办?——开始咱们的跨域之旅。(当然用iframe也可以实现)

    2. 从“盗链”说起

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

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

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

    重点:<img>的src(获取图片),<link>的href(获取css),<script>的src(获取javascript)这三个都不符合同源策略,它们可以跨域获取数据。因此,你可以直接从一些cdn上获取jQuery,并且你网站上的图片也随时可能被别人盗用,所有最好加上水印!

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

    3. JSONP

    例如,域名 下有一个 网页,域名 下有一个 网页和 文件。

    引导第一步:简单引用js

    编写 如下:

    alert(123);
    

    编写如下代码:

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

    运行 ,结果很明显,就是弹出 【123】 。

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

    修改为:

    myFn(100);
    

    修改为:

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

    运行 ,结果是弹出【 100px 】,这个应该也没有什么疑问。

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

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

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

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

    引导第四步:引用html格式

    <script>的src不一定仅仅指向javascript文件,可以指向任何地址。例如:

    修改为:

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

    编写为:(注意,data.html中就写以下一行代码,多了不写)

    myFn(100); 
    

    运行 ,结果依然是【 100px 】

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

    引导第五步:动态数据

    如果要请求的数据是动态的,那就要在动态页面中编写。

    那么我们就让 去调用一个动态的aspx页面:

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

    大家注意,我们在 src 地址中增加了“?callback=myFn”,意思是把显示数据的函数也动态传过去了,而第二步、第四步都是静态的写在被调用的文件中的。

    至于callback参数后台如何接收,如何使用,请接着看:

    下增加一个 页面,后台代码如下:



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

    代码很简单,获取callback参数,然后组成一个函数的形式返回。如果“”调用的话,那么返回的就是" myFn(1024) "。

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

    引导第六步:调用封装

    中,仅仅有一个<script>静静的躺在那里,执行一次之后,就没有作用了。

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



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

    4. 总结

    以前我们引入的是函数,在script里面写的是函数的执行。

    现在用jsonp相当于引入函数的执行命令, 在script里面写的是函数声明。

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

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

  • 相关阅读:
    openSUSE 13.1 Milestone 4 发布
    Neo4j 2.0 M4 发布
    iBoxDB for .NET v1.5发布, 移动NoSQL数据库
    GNU libc (Glibc) 2.18 发布
    Android 开源项目维护者宣布退出
    Jeasyframe 开源框架 稳定版 V1.5 发布
    Spring Mobile 1.1.0.RC1 和 1.0.2 发布
    Deis logo 开源PaaS系统 Deis
    EasyCriteria 3.0 发布
    TypeScript 0.9.1 发布,新增 typeof 关键字
  • 原文地址:https://www.cnblogs.com/roashley/p/8799002.html
Copyright © 2011-2022 走看看