日期:2014-05-16  浏览次数:20860 次

转一个大神的ajax跨域请求总结留待以后参考
http://www.cnblogs.com/SanMaoSpace/p/3144851.html
1.什么是跨域?
跨域,JavaScript出于安全方面的考虑,不允许跨域调用其他页面的对象。简单地理解就是因为JavaScript同源策略的限制,a.com 域名下的js无法操作b.com或是c.a.com域名下的对象。
同源策略,它是由Netscape提出的一个著名的安全策略。现在所有支持JavaScript 的浏览器都会使用这个策略。所谓同源是指,域名,协议,端口相同。当一个浏览器的两个tab页中分别打开来 百度和谷歌的页面当一个百度浏览器执行一个脚本的时候会检查这个脚本是属于哪个页面的,即检查是否同源,只有和百度同源的脚本才会被执行。
更详细的说明可以看下表:

URL 说明 是否允许通信
http://www.a.com/a.js
http://www.a.com/b.js 同一域名下 允许
http://www.a.com/lab/a.js
http://www.a.com/script/b.js 同一域名下不同文件夹 允许
http://www.a.com:8000/a.js
http://www.a.com/b.js 同一域名,不同端口 不允许
http://www.a.com/a.js
https://www.a.com/b.js 同一域名,不同协议 不允许
http://www.a.com/a.js
http://70.32.92.74/b.js 域名和域名对应ip 不允许
http://www.a.com/a.js
http://script.a.com/b.js 主域相同,子域不同 不允许
http://www.a.com/a.js
http://a.com/b.js 同一域名,不同二级域名(同上) 不允许(cookie这种情况下也不允许访问
http://www.cnblogs.com/a.js
http://www.a.com/b.js 不同域名 不允许
特别注意两点:
(1).如果是协议和端口造成的跨域问题“前台”是无能为力的,
(2).在跨域问题上,域仅仅是通过“URL的首部”来识别而不会去尝试判断相同的ip地址对应着两个域或两个域是否在同一个ip上。
“URL的首部”指window.location.protocol +window.location.host,也可以理解为“Domains, protocols and ports must match”。

2.跨域请求数据解决方案
(1).document.domain+iframe的设置
对于主域相同而子域不同的例子,可以通过设置document.domain的办法来解决。
(2).动态创建Script
虽然浏览器默认禁止了跨域访问,但并不禁止在页面中引用其他域的JS文件,并可以自由执行引入的JS文件中的function(包括操作cookie、Dom等等)。
(3).利用iframe和location.hash
这个办法比较绕,但是可以解决完全跨域情况下的脚步置换问题。原理是利用location.hash来进行传值。
(4).Window.name实现的跨域数据传输
iframe的src属性由外域转向本地域,跨域数据即由iframe的window.name从外域传递到本地域。这个就巧妙地绕过了浏览器的跨域访问限制,但同时它又是安全操作。
(5).使用HTML5 postMessage
HTML5中最酷的新功能之一就是 跨文档消息传输Cross Document Messaging。
(6).利用flash
上述,六种方式都可以处理JavaScript的跨域请求数据问题,详细参见:Rain Man的《JavaScript跨域总结与解决办法》。
除了上面六种方式,大家平时估计都在用脚本框架开发,在JQuery框架和ExtJs框架中处理JS跨域问题,常用JSONP来处理。

3.什么是JSONP?
JSONP(JSON with Padding)是一个非官方的协议,它允许在服务器端集成Script Tags返回至客户端,通过Javascript callback的形式实现跨域访问(这仅仅是JSONP简单的实现形式)。
由于同源策略的限制,XMLHttpRequest只允许请求当前源(域名、协议、端口)的资源,为了实现跨域请求,可以通过script标签实现跨域请求,然后在服务端输出JSON数据并执行回调函数,从而解决了跨域的数据请求。

4..JSONP如何产生的?
(1).跨域访问无权限。
众所周知的问题,Ajax直接请求普通文件存在跨域无权限访问的问题,不管是静态页面、动态网页、web服务、WCF,只要是跨域请求,都无权限;
(2)."src"属性标签有跨域能力。
发现在Web页面上调用js文件时则不受是否跨域的影响(不仅如此,拥有"src"属性的标签都拥有跨域能力,比如<script>、<img>、<iframe>);
(3).将数据装进JS格式数据。
如果想通过纯Web端(ActiveX控件、服务端代理、HTML5之Websocket等方式不算)跨域访问数据就只有一种可能,就是在远程服务器上设法把数据装进js格式的数据里,供客户端调用和进一步处理;
(4).JSON格式承载数据适合。
有一种JSON的纯字符数据格式可以简洁的描述复杂数据,更妙的是JSON还被JS原生支持,所以在客户端几乎可以随心所欲的处理这种格式的数据;
(5).动态生成JSON格式数据。
Web客户端可以通过与调用脚本一模一样的方式,来调用跨域服务器上动态生成的js格式文件,显而易见,服务器之所以要动态生成JSON文件,目的在于把客户端需要的数据装入进去。
(6).JSON数据成功回调到客户端。
客户端在对JSON文件调用成功之后,也就获得了自己所需的数据,剩下的就是按照自己需求进行处理和展现了,这种获取远程数据的方式看起来非常像AJAX,但实质上是不一样。
(7).形成一种非正式传输协议JSONP。
为了便于客户端使用数据,逐渐形成了一种非正式传输协议,人们把它称作JSONP,该协议的一个要点就是允许用户传递一个callback参数给服务端,然后服务端返回数据时会将这个callback参数作为函数名来包裹住JSON数据,这样客户端就可以随意定制自己的函数来自动处理返回的数据。

5.JSONP的工作原理
JSONP的原理:创建一个回调函数,动态创建Script标签,然后在远程服务上调用这个函数并且将JSON 数据形式作为参数传递,完成回调。将JSON数据填充进回调函数,进行相关的逻辑处理,或许这就是JSONP的JSON+Padding的含义。
(1).跨域简单原理
新建一个asp.net的web程序,添加sample.html网页和一个test.js文件,代码如下:
sample.html的代码:


<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" >
  <head>
    <title>test</title>
    <script type="text/javascript" src="test.js"></script>
  </head>
  <body>
  </body>
</html>

test.js的代码:

alert("success");
打开sample.html后会跳出"success”这样的这样的信息框,这似乎并不能说明什么, 跨域问题到底怎么解决呢?
现在模拟非同源的环境,把上面的Web程序叫做A程序,再新建一个Web程序叫做B程序,将A程序的test.js文件移除然后拷贝到B程序中。将两个程序都运行起来,Visual Studio会启动内置服务器,假设A程序是localhost:20001,B程序是localhost:200