zoukankan      html  css  js  c++  java
  • 一个小例子讲讲jsonp

    1.何为jsonp(json with padding)

      json我们都知道并用过。那么jsonp呢,呃,好像听过,但没用过。很久以来楼主也只是听过这个名词而已。直到今晚楼主看到一篇文章(http://www.cnblogs.com/twobin/p/3395086.html),然后决定探究一下什么是jsonp。

      我们都知道js文件是不能跨域操作内容的,这在js里面叫做‘同源策略’,意即js文件只能操作相同域名、相同端口、相同协议的html文档。但同时我们知道浏览器允许跨源请求<script>资源,例如可以通过指定<script>标签的src属性去请求其它域名的js文件,例如我们常常如此引用jquery文件,<script src = 'code.jquery.com/jquery-latest.min.js'></script>,然后我们就能使用jquery里的方法来任意操作我们html文档里的内容了。

      嗯,jsonp就是利用这一原理实现的跨域访问数据。说白了,其实jsonp技术本质上就是创建<script>标签,并把其src指向跨域地址而实现跨域获取数据。通常的做法就是,异步请求跨域的服务器端时,不直接返回数据而是返回一个js方法调用,将真正的数据作为该js方法调用的参数传过来。

    2.jsonp实例

      原理不多说,下面以百度搜索为例讲讲jsonp的用法。当我们在百度首页输入关键字时,会出现下拉联想框。实际当我们在文本框中输入每一个关键字时都会动态构建一个<script>标签,访标签会将我们输入的关键字作为请求参数传递给suggestion.baidu.com。注意图中标红的部分:

    在这里创建了<script src="http://suggestion.baidu.com/su?wd=ipad&amp;p=3&amp;cb=window.bdsug.sug&amp;sid=&amp;t=1383236316435" charset="gb2312"></script>。

      该标签src指向的域名是suggestion.baidu.com(三级域名),与我们访问的baidu.com(二级域名)不是同一个域名,在这个请求中我们指定了wd = ipad, cb = window.bgsug.sug,合理推测cb就是baidu.com文档里包含的js方法,该方法会处理从suggestion.baidu.com返回的针对wd = ipad的响应。

      看到这个<script>请求的返回内容,最终我们在baidu.com页面的home.js文件中寻找到了window.bdsug.sug方法:

    相关代码如下,

    1.其中getDataScript方法根据用户输入的关键字,构建相关的<script>标签向suggestion.baidu.com发起请求

    2.bdsug.sug方法为收到suggestion.baidu.com响应后的处理函数

    var Request = (function() {
            var dataElm;
            var cookieSwitch;
            function getDataScript(wd) {
                var requestUrl = bds.comm.sugHost || "http://suggestion.baidu.com/su";
                Request.dm({type: "need_cookie"});
                if (dataElm) {
                    document.body.removeChild(dataElm)
                }
                dataElm = C("SCRIPT");
                dataElm.src = requestUrl + "?wd=" + encodeURIComponent(wd) + "&p=" + cookieSwitch + "&cb=window.bdsug.sug&sid=" + bds.comm.sid + "&t=" + (new Date()).getTime();
                dataElm.charset = "gb2312";
                document.body.appendChild(dataElm);
                addTj({rsv_sug3: ++rsv_sug3});
                rsv_temp_time = new Date().getTime();
                rsv_temp_flag = false;
                rsv_timer = setTimeout(function() {
                    addTj({rsv_sug4: rsv_sug4 += 5000});
                    rsv_temp_flag = true
                }, 5000)
            }
            return MessageDispatcher.ini({rm: function(evtObj) {
                    switch (evtObj.type) {
                        case "request_data":
                            getDataScript(evtObj.wd);
                            break;
                        case "give_cookie":
                            var _sug = evtObj.sug;
                            if (_sug > 0) {
                                _sug = 3
                            }
                            cookieSwitch = _sug;
                            break
                    }
                }})
        })();
        bdsug.sug = function(dataObj) {
            bdsug.dm({type: "response_data",data: dataObj});
            if (!rsv_temp_flag) {
                var ipt = G("kw");
                if (ipt.value.toLowerCase() == dataObj.q) {
                    addTj({rsv_sug1: ++rsv_sug1})
                }
                clearTimeout(rsv_timer);
                addTj({rsv_sug4: rsv_sug4 += (new Date().getTime() - rsv_temp_time)})
            }
        };

     最后我们总结一下整个流程:

    1.在baidu.com输入框中键入关键字

    2.动态构建<script src="http://suggestion.baidu.com/su?wd=你输入的关键字&amp;p=3&amp;cb=window.bdsug.sug...></script>向suggestion.baidu.com发起请求

    3.suggestion.baidu.com返回内容 'window.bdsug.sug({q:"ipad",p:false,s:["ipad4","ipad mini","ipad5","ipad mini2","ipad air","ipad2"}])'

    4.调用baidu.com页面home.js中的bdsug.sug方法,构建下拉联想列表。

    另见我自己做的百度首页:

    http://caochao.github.io/jsonp.html

    参见stackoverflow关于what is jsonp的讨论帖子:

    http://stackoverflow.com/questions/2067472/what-is-jsonp-all-about

  • 相关阅读:
    Sqlite框架Delphi10.3(07)
    FastReport 6.8.11在Delphi10.3上的安装
    Delphi 中,InputQuery 函数的妙用
    Javaday25(sax解析xml,json,设计模式)
    并发学习第五篇——volatile关键字
    并发学习第四篇——synchronized关键字
    并发学习第二篇——Thread
    并发学习第一篇——Runnable
    git-仓库迁移并保留commit log
    并发编程理论基础二——画图理解
  • 原文地址:https://www.cnblogs.com/tudas/p/what-is-jsonp.html
Copyright © 2011-2022 走看看