技术头条 - 一个快速在微博传播文章的方式     搜索本站
您现在的位置首页 --> JavaScript --> jQuery中getJSON跨域原理详解

jQuery中getJSON跨域原理详解

浏览:5639次  出处信息

前几天我再开发一个叫 河蟹工具条 的时候,其中有个功能就是获取本页面的短网址。

这个想法是好的,可是在我付诸于行动的时候,发现这个需要跨域。

起初我的想法就是,跨域的最简单的方法就是增加一个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();
})();

建议继续学习:

  1. JQuery实现Excel表格呈现    (阅读:46536)
  2. 分享一个JQUERY颜色选择插件    (阅读:12722)
  3. jQuery插件---轻量级的弹出窗口wBox.    (阅读:9705)
  4. 10个强大的Ajax jQuery文件上传程序    (阅读:7779)
  5. jQuery的data()方法    (阅读:7636)
  6. jQuery性能优化指南    (阅读:7382)
  7. jQuery Color Animations颜色动画插件    (阅读:7145)
  8. 优雅绝妙的Javascript跨域问题解决方案    (阅读:6758)
  9. 精于图片处理的10款jQuery插件    (阅读:6283)
  10. 跨域请求的iframe解决方案(1)    (阅读:5409)
QQ技术交流群:445447336,欢迎加入!
扫一扫订阅我的微信号:IT技术博客大学习
© 2009 - 2024 by blogread.cn 微博:@IT技术博客大学习

京ICP备15002552号-1