jQuery跨域原理

JQuery 的跨域方法这篇文章作者给出了使用jQuery中的getJSON方法实现跨域的方法;示例代码没有问题,但是作者把getJSON跨域的原理解释成:

“因为getJSON跨域的原理是把? 随机变一个方法名,然后返回执行的,实现跨域响应的目的。”

这个未免草率了一些,是这么回事 ?Firebug里面监控的结果貌似也是这意思,本文试图探究jQuery getJson跨域的原理;

盐从哪儿咸:为什么有跨域的问题

跨域问题存在实际上源于浏览器的同源策略(same origin policy),简单讲,同源就是要求域名,协议,端口三者都一致;而同源策略就是指页面上的脚本不能访问非同源的资源(包括HTTP响应和Cookie);上面给出了维基百科的地址,如果无法正常访问请移步这里:same origin policy

很多人会想到一个很熟悉的东西:document.domain

同源策略有点放松的就是:b.a.com上的页面无法通过a.com的同源验证,但是设置b.a.com页面的document.domain属性为a.com,就可以通过浏览器对a.com的同源检测;但是,document.domain只允许设置成更上级的域名,而不是其它域名,例如c.com就不行; 提到这里很多人都会想到多级域名下共享Cookie的路子就是把Cooki设置成上级域名;在Web2.0的时代,这种本质上同域跨级解决方案远远不能满足我们跨域的需求;

jQuery的解决方案

浏览器会进行同源检查,这导致了跨域问题,然而这个跨域检查还有一个例外那就是HTML的<Script>标记;我们经常使用<Script>的src属性,脚本静态资源放在独立域名下或者来自其它站点的时候这里是一个url;这个url响应的结果可以有很多种,比如JSON,返回的Json值成为<Script>标签的src属性值。这种属性值变化并不会引起页面的影响。按照惯例,浏览器在URL的查询字符串中提供一个参数,这个参数将作为结果的前缀一起返回到浏览器;

看下面的例子:


以下为引用的内容:

<script type="text/javascript"          src="http://domain2.com/getjson?jsonp=parseResponse"> </script>响应值:parseResponse({"Name": "Cheeso", "Rank": 7})

这种方式被称作JsonP;(如果链接已经失效请点击这里:JSONP);即:JSON with padding 上面提到的前缀就是所谓的“padding”。那么jQuery里面是怎么实现的呢?

貌似并没有<Script>标记的出现。?OKay,翻看源码来看:


以下为引用的内容:

1 页面调用的是getJSON:
2
3 getJSON: function( url, data, callback ) {
4         return jQuery.get(url, data, callback, "json");
5     },
6
7
8 继续跟进
9
10         get: function( url, data, callback, type ) {
11             // shift arguments if data argument was omited
12              if ( jQuery.isFunction( data ) ) {
13                 type = type || callback;
14                 callback = data;
1

5                 data = null;
16             }
17    
18             return jQuery.ajax({
19                 type: "GET",
20                 url: url,
21                 data: data,
22                 success: callback,
23                 dataType: type
24             });
25        
26  

跟进jQuery.ajax,下面是ajax方法的代码片段:


以下为引用的内容:

 1 // Build temporary JSONP function
 2      if ( s.dataType === "json" && (s.data && jsre.test(s.data) || jsre.test(s.url)) ) {
 3         jsonp = s.jsonpCallback || ("jsonp" + jsc++);
 4 
 5         // Replace the =? sequence both in the query string and the data
 6          if ( s.data ) {
 7             s.data = (s.data + "").replace(jsre, "=" + jsonp + "$1");
 8         }
 9
10         s.url = s.url.replace(jsre, "=" + jsonp + "$1");
11
12         // We need to make sure
13          // that a JSONP style response is executed properly
14          s.dataType = "script";
15
16         // Handle JSONP-style loading
17          window[ jsonp ] = window[ jsonp ] || function( tmp ) {
18             data = tmp;
19             success();
20             complete();
21             // Garbage collect
22              window[ jsonp ] = undefined;
23
24             try {
25                 delete window[ jsonp ];
26             } catch(e) {}
27
28             if ( head ) {
29                 head.removeChild( script );
30             }
31         };
32     }
33
34     if ( s.dataType === "script" && s.cache === null ) {
35         s.cache = false;
36     }
37
38     if ( s.cache === false && type === "GET" ) {
39         var ts = now();
40
41         // try replacing _= if it is there
42          var ret = s.url.replace(rts, "$1_=" + ts + "$2");
43
44         // if nothing was replaced, add timestamp to the end
45          s.url = ret + ((ret === s.url) ? (rquery.test(s.url) ? "&" : "?") + "_=" + ts : "");
46     }
47
48     // If data is available, append data to url for get requests
49      if ( s.data && type === "GET" ) {
50         s.url += (rquery.test(s.url) ? "&" : "?") + s.data;
51     }
52
53     // Watch for a new set of requests
54      if ( s.global && ! jQuery.active++ ) {
55         jQuery.event.trigger( "ajaxStart" );
56     }
57
58     // Matches an absolute URL, and saves the domain
59      var parts = rurl.exec( s.url ),
60         remote = parts && (parts[1] && parts[1] !== location.protocol || parts[2] !== location.host);
61
62     // If we're requesting a remote document
63      // and trying to load JSON or Script with a GET
64      if ( s.dataType === "script" && type === "GET" && remote ) {
65         var head = document.getElementsByTagName("head")[0] || document.documentElement;
66         var script = document.createElement("script");
67         script.src = s.url;
68         if ( s.scriptCharset ) {
69             script.charset = s.scriptCharset;
70         }
71
72         // Handle Script loading
73          if ( !jsonp ) {
74             var done = false;
75
76             // Attach handlers for all browsers
77              script.onload = script.onreadystatechange = function() {
78                 if ( !done && (!this.readyState ||
79                         this.readyState === "loaded" || this.readyState === "complete") ) {
80                     done = true;
81                     success();
82                     complete();
83
84                     // Handle memory leak in IE
85                      script.onload = script.onreadystatechange = null;
86                     if ( head && script.parentNode ) {
87                         head.removeChild( script );
88                     }
89                 }
90             };
91         }
92
93         // Use insertBefore instead of appendChild  to circumvent an IE6 bug.
94          // This arises when a base node is used (#2709 and #4378).
95          head.insertBefore( script, head.firstChild );
96
97         // We handle everything using the script element injection
98          return undefined;
99     }
100  

上面的代码第1行到第10行:判断是JSON类型调用,为本次调用创建临时的JsonP方法,并且添加了一个随机数字,这个数字源于用日期值;

这个地方也就是Taven.李锡远所说的“随机变一个方法名”;

关注第14行,这一行相当关键,注定了我们的结果最终是<Script>;然后是构造Script片段,第95行在Head中添加该片段,修成正果; 不仅仅是jQuery,很多js框架都是用了同样的跨域方案,说到这里,嗯,这就是getJSON跨域的原理,赵本山说了“情况呢就是这么个情况”

以上是小编为您精心准备的的内容,在的博客、问答、公众号、人物、课程等栏目也有的相关内容,欢迎继续使用右上角搜索按钮进行搜索jquery
, url
, jsonp
, script
, 跨域
, jquery&amp;#39; is undefined
, data
, document
, jquery script
, jsc#
, jsonp解决ajax跨域
, html5_ajax跨域访问
, jquery跨域访问
同源
jquery ajax跨域原理、jquery 跨域请求、jquery ajax 跨域请求、jquery 跨域、jquery ajax跨域,以便于您获取更多的相关知识。

时间: 2024-12-21 23:11:33

jQuery跨域原理的相关文章

jQuery中getJSON跨域原理详解

jQuery中getJSON跨域原理详解  前几天我再开发一个叫 河蟹工具条 的时候,其中有个功能就是获取本页面的短网址. 这个想法是好的,可是在我付诸于行动的时候,发现这个需要跨域. 起初我的想法就是,跨域的最简单的方法就是增加一个script标签,因为script标签是允许跨域的. 但是问题又来了,对方的API返回的是个json对象,用script标签只能执行,却不能获取到里面的东西,也就是说返回的东西是不可控的. 随后我就想到了jQuery中的getJSON的方法,学习了一下,没想到里面的

jQuery 跨域访问解决原理案例详解_jquery

浏览器端跨域访问一直是个问题,多数研发人员对待js的态度都是好了伤疤忘了疼,所以病发的时候,时不时地都要疼上一疼.记得很久以前使用iframe 加script domain 声明.yahoo js util 的方式解决二级域名跨域访问的问题. 时间过得好快,又被拉回js战场时, 跨域问题这个伤疤又开疼了.好在,有jQuery帮忙,跨域问题似乎没那么难缠了.这次也借此机会对跨域问题来给刨根问底,结合实际的开发项目,查阅了相关资料,算是解决了跨域问题...有必要记下来备忘, 跨域的安全限制都是指浏览

详解js跨域原理以及2种解决方案_javascript技巧

1.什么是跨域 我们经常会在页面上使用ajax请求访问其他服务器的数据,此时,客户端会出现跨域问题. 跨域问题是由于javascript语言安全限制中的同源策略造成的. 简单来说,同源策略是指一段脚本只能读取来自同一来源的窗口和文档的属性,这里的同一来源指的是主机名.协议和端口号的组合. 例如: 2.实现原理 在HTML DOM中,Script标签是可以跨域访问服务器上的数据的.因此,可以指定script的src属性为跨域的url,从而实现跨域访问. 例如: 这种访问方式是不行的.但是如下方式,

jquery 跨域访问问题解决方法(笔记)_jquery

这两天需要实现三级域名直接url rewrite到网站静态页面,如 http://123.456.789.com/ UrlRewrite到http://www.789.com/news/123.html 说到这里,也许和js跨域访问没有半点关系,在脑海里排列这的问题都是和UrlRewrite相关的.好吧现在URLRewrite一切就绪,直接在浏览器地址栏中输入http://123.456.789.com/ 会发现,这个在地址栏直接通过http://www.789.com/news/123.htm

Jquery跨域获得Json的简单实例_jquery

这两天用 Jquery 跨域取数据的时候,经常碰到 invalid label 这个错误,十分的郁闷,老是取不到服务器端发送回来的 json 值, 一般跨域用到的两个方法为:$.ajax 和$.getJSON 最后,仔细安静下来,细读 json 官方文档后发现这么一段: JSON数据是一种能很方便通过JavaScript解析的结构化数据.如果获取的数据文件存放在远程服务器上(域名不同,也就是跨域获取数据),则需要使用jsonp类型.使用这种类型的话,会创建一个查询字符串参数 callback=?

Jquery跨域获得Json时invalid label错误的解决办法_jquery

最后,仔细安静下来,细读 json 官方文档后发现这么一段: JSON数据是一种能很方便通过JavaScript解析的结构化数据.如果获取的数据文件存放在远程服务器上(域名不同,也就是跨域获取数据),则需要使用jsonp类型.使用这种类型的话,会创建一个查询字符串参数 callback=? ,这个参数会加在请求的URL后面.服务器端应当在JSON数据前加上回调函数名,以便完成一个有效的JSONP请求.如果要指定回调函数的参数名来取代默认的callback,可以通过设置$.ajax()的jsonp

jquery跨域3

这两天用 Jquery 跨域取数据的时候,经常碰到 invalid label 这个错误,十分的郁闷,老是取不到服务器端发送回来的 json 值, 一般跨域用到的两个方法为:$.ajax 和$.getJSON   最后,仔细安静下来,细读 json 官方文档后发现这么一段:   JSON数据是一种能很方便通过JavaScript解析的结构化数据.如果获取的数据文件存放在远程服务器上(域名不同,也就是跨域获取数据),则需要使用jsonp类型.使用这种类型的话,会创建一个查询字符串参数 callba

jquery跨域请求示例分享

 这篇文章主要介绍了jquery跨域请求示例(jquery发送ajax请求),需要的朋友可以参考下 jQuery中常用getJSON来调用并获取远程的JSON字符串,将其转换为JSON对象,如果成功,则执行回调函数.原型如下:   jQuery.getJSON( url, [data], [callback] ) 跨域加载JSON数据.   url: 发送请求的地址 data : (可选) 待发送key/value参数 callback: (可选) 载入成功时的回调函数 主要用于客户端获取服务器

深入理解jquery跨域请求方法_jquery

项目中关于ajax jsonp的使用, 出现了问题:可以成功获得请求结果,但没有执行success方法 总算搞定了,记录一下 function TestAjax() { $.ajax({ type : "get", async : false, url : "ajaxHandler.ashx", //实际上访问时产生的地址为: ajax.ashx?callbackfun=jsonpCallback&id=10 data : {id : 10}, cache