jQuery中getJSON跨域原理的深入讲解

所属分类: 网络编程 / JavaScript 阅读数: 490
收藏 0 赞 0 分享

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

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

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

总结

更多精彩内容其他人还在看

微信小程序对接七牛云存储的方法

本篇文章主要介绍了小程序对接七牛云存储的方法,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
收藏 0 赞 0 分享

jquery easyui如何实现格式化列

本篇文章主要介绍了jquery easyui如何实现格式化列 ,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
收藏 0 赞 0 分享

关于前后端json数据的发送与接收详解

这篇文章主要给大家介绍了关于前后端json数据发送与接收的相关资料,文中通过示例代码详细介绍了关于flask中的json数据接收和前端发送json数据等内容,需要的朋友可以参考借鉴,下面来一起看看吧。
收藏 0 赞 0 分享

Angular.js中上传指令ng-upload的基本使用教程

这篇文章主要给大家介绍了关于Angular.js中上传指令ng-upload的基本使用方法,文中通过示例代码介绍的非常详细,对大家具有一定的参考学习价值,需要的朋友们下面跟着小编来一起学习学习吧。
收藏 0 赞 0 分享

利用JavaScript如何查询某个值是否数组内

这篇文章主要给大家介绍了关于利用JavaScript如何查询某个值是否数组内的相关资料,文中通过示例代码分别介绍了实现该问题的一些解决方法是否可行,需要的朋友可以参考借鉴,下面跟着小编来一起学习学习吧。
收藏 0 赞 0 分享

webpack实现热加载自动刷新的方法

本文介绍了webpack实现热加载自动刷新的方法,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
收藏 0 赞 0 分享

Vue的Flux框架之Vuex状态管理器

本文内容主要参考官方教程,为了方便理解,用更加通俗的文字讲解Vuex,也原文内容做一些重点引用。希望会对你有所帮助。
收藏 0 赞 0 分享

Angular.js中$resource高大上的数据交互详解

这篇文章主要给大家介绍了关于Angular.js中$resource高大上的数据交互的相关资料,文中通过示例代码介绍的非常详细,对大家学习或者使用angular.js具有一定的参考学习价值,需要的朋友们下面跟着小编来一起看看吧。
收藏 0 赞 0 分享

webpack配置sass模块的加载的方法

本篇文章主要介绍了webpack加载sass配置,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
收藏 0 赞 0 分享

Vue框架中正确引入JS库的方法介绍

最近在学习使用vue框架,在使用中遇到了一个问题,查找相关资料终于找了正确的姿势,所以这篇文章主要给大家介绍了关于在Vue框架中正确引入JS库的方法,需要的朋友可以参考借鉴,下面来一起看看吧。
收藏 0 赞 0 分享
查看更多