博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
jQuery中getJSON跨域原理详解
阅读量:4633 次
发布时间:2019-06-09

本文共 2199 字,大约阅读时间需要 7 分钟。

详见:
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();
})();

转载于:https://www.cnblogs.com/grefr/p/5046342.html

你可能感兴趣的文章
C - 娜娜梦游仙境系列——吃不完的糖果
查看>>
巴黎公社社员造船厂Project1129研制成功
查看>>
poj2007极角排序
查看>>
POJ 1204 Word Puzzles
查看>>
JEESZ分布式框架--单点登录集成方案
查看>>
三元表达式,列表生成式,字典生成式,生成器表达式
查看>>
.net core集成 vue
查看>>
ZOJ3829---模拟,贪心
查看>>
Windows XP系列全下载(均为MSDN原版)
查看>>
如何提高ASP.NET性能
查看>>
vh属性-- 一个永远垂直居中的弹出框
查看>>
LAMP集群项目三 配置业务服务器
查看>>
《Unity_API解析》 第五章 Mathf类
查看>>
计算器
查看>>
批处理备份
查看>>
To the Max(矩阵压缩)
查看>>
数组的学习+冒泡排序
查看>>
C程序设计语言----第1章 导言(一)
查看>>
asp.net文件下载
查看>>
APK IPA --------------- iis7如何添加mime类型支持所有后缀名文件下载的方法(解决特殊后缀文件无法下载的问题)...
查看>>