zoukankan      html  css  js  c++  java
  • jQuery中getJSON跨域原理详解

    详见:http://blog.yemou.net/article/query/info/tytfjhfascvhzxcytp28

    jQuery中getJSON跨域原理详解


    前几天我再开发一个叫 河蟹工具条 的时候,其中有个功能就是获取本页面的短网址。
    这个想法是好的,可是在我付诸于行动的时候,发现这个需要跨域。
    起初我的想法就是,跨域的最简单的方法就是增加一个script标签,因为script标签是允许跨域的。
    但是问题又来了,对方的API返回的是个json对象,用script标签只能执行,却不能获取到里面的东西,也就是说返回的东西是不可控的。
    随后我就想到了jQuery中的getJSON的方法,学习了一下,没想到里面的文章这么大。
    jQuery非常聪明,他也意识到只靠script请求是无法接受到返回的东西的,所以他就设计了一个全局的callback函数,发送请求的时候把这个callback函数也传进去。
    服务器判断是否有这个callback函数,如果没有就返回一个对象,如果有就返回一个函数名(对象)。
    我们可以通过下面这个地址来看一下
    http://to.ly/api.php?json=1&longurl=http%3A%2F%2Fwww.skiyo.cn
    大家可以打开一下,结果返回的是一个json对象。
    如果我加上callback参数
    http://to.ly/api.php?json=1&longurl=http%3A%2F%2Fwww.skiyo.cn&callback=somefunc
    大家可以看到返回的是
    somefunc({“shorturl”: “http://to.ly/3XHP”, “ok”: true})
    传入的也正好是函数名。
    这个想法很不错,缺点就是对方服务器必须是可控的。
    大方向是这个的,但是还有一些细节的小技巧,比如说如何在匿名函数中设置一个全局函数,如何将这个全局函数变为匿名函数!
    本来想直接把jQuery中的getJSON拿来直接用的,可是看了才知道,jQuery的ajax方法都混合到一起了,想剥落下来也不是一件容易的事。
    庆幸的是我还懂一点JavaScript,经过我的加工与修改,下面的例子已经可以正常使用。详细的可以查看注释。
    以下是代码片段:
    (function() {
            var cross = {
                    //设置一个随机的callback函数..防止跟其他的全局函数重名
                    callback : 'cross' + parseInt(Math.random()*1000),
                    init : function() {
                            this.getJSON('http://to.ly/api.php?json=1&longurl='+encodeURIComponent('http://www.skiyo.cn/'), function(data){
                                    alert(data.shorturl);
                            });
                    },
                    getJSON : function(url, callback) {
                            var c = this.callback;
                            url = url + "&callback=" + c;
                            // Handle JSONP-style loading
                            //将函数名设置为window的一个方法,这样此方法就是全局的了.
                            window[ c ] = window[ c ] || function( data ) {
                                    //调用匿名函数
                                    callback(data);
                                    // Garbage collect
                                    window[ c ] = undefined;
                                    try {
                                            delete window[ c ];
                                    } catch(e) {}
                                    if ( head ) {
                                            head.removeChild( script );
                                    }
                            };
                            var head = document.getElementsByTagName("head")[0] || document.documentElement;
                            var script = document.createElement("script");
                            script.src = url;
                            // Handle Script loading
                            var done = false;
                            // Attach handlers for all browsers
                            script.onload = script.onreadystatechange = function() {
                                    if ( !done && (!this.readyState
                                                    this.readyState === "loaded" || this.readyState === "complete") ) {
                                            done = true;
                                            // Handle memory leak in IE
                                            script.onload = script.onreadystatechange = null;
                                            if ( head && script.parentNode ) {
                                                    head.removeChild( script );
                                            }
                                    }
                            };
                            head.insertBefore( script, head.firstChild );
                    },
            };
            //go
            cross.init();
    })();

  • 相关阅读:
    Android高效加载大图、多图解决方案,有效避免程序OOM
    修改Eclipse中项目在Apache Tomcat中的部署路径
    解决用户绕过Servlet直接访问jsp页面
    Java中文件的上传与下载
    Android菜鸟的成长笔记(1)——Android开发环境搭建从入门到精通
    Linux学习(1)vi编辑器的常用命令
    怎样获取运行计划
    如​何​使​用​P​H​P​开​发​高​效​的​W​E​B​系​统
    网页抓取信息(php正則表達式、php操作excel)
    hdu1078 记忆化搜索
  • 原文地址:https://www.cnblogs.com/grefr/p/5046342.html
Copyright © 2011-2022 走看看