1、神马是跨域(Cross Domain)
说白点就是post、get的url不是你当前的网站,域名不同。例如在aaa.com/a.html里面,表单的提交action是bbb.com/b.html。
不仅如此,www.aaa.com和aaa.com之间也属于跨域,因为www.aaa.com是二级域名,aaa.com是根域名。
JavaScript出于安全方面的考虑,是不允许跨域调用其他页面的对象的(同源策略 Same-Origin Policy)。
关于JavaScript能否跨域通信的详细说明,见下表:
http://www.a.com/a.js访问以下URL的结果
URL 说明 是否允许通信
http://www.a.com/b.js | 同一域名下 | 允许 |
http://www.a.com/script/b.js | 同一域名下不同文件夹 | 允许 |
http://www.a.com:8000/b.js | 同一域名,不同端口 | 不允许 |
https://www.a.com/b.js | 同一域名,不同协议 | 不允许 |
http://70.32.92.74/b.js | 域名和域名对应ip | 不允许 |
http://script.a.com/b.js | 主域相同,子域不同 | 不允许 |
http://a.com/b.js | 同一域名,不同二级域名(同上) | 不允许 |
http://www.b.com/b.js | 不同域名 | 不允许 |
2、为嘛要跨域
跨域这东西其实很常见,例如我们可以把网站的一些脚本、图片或其他资源放到另外一个站点。例如我们可以使用Google提供的jQuery,加载时间少了,而且减少了服务器的流量,如下:
1
|
< script type = "text/java script" src = "https://aja x.googleapis.com/aj ax/libs/jquery/1.4.2/jquery.min.js" ></ script >
|
有时候不仅仅是一些脚本、图片这样的资源,我们也会希望从另外的站点调用一些数据(有时候是不得不这样),例如我希望获取一些blog的RSS来生成一些内容,再或者说我在“人人开放平台”上开发一个应用,需要调用人人的数据。
然而,很不幸的是,直接用XMLHttpRequest来Get或者Post是不行的,例如我用jQuery的$.get去访问本小博的主域名 :
1
2
3
4
|
结果如下(总之就是不行啦~FF不报错,但是木有返回数据):
那咋么办捏?(弱弱的说,测试的时候我发现IE访问本地文件时,是可以跨域的,不过这也没啥用~囧~)
3、肿么跨域
下面为了更好的讲解和测试,我们可以通过修改hosts文件来模拟跨域的效果,hosts文件在C:\Windows\System32\drivers\etc 文件夹下。在下面加3行:
127.0.0.1 www.a.com
127.0.0.1 a.com
127.0.0.1 www.b.com
3.1、跨域代理
一种简单的办法,就是把跨域的工作交给服务器,从后台获取其他站点的数据再返回给前台,也就是跨域代理(Cross Domain Proxy)。
这种方法似乎蛮简单的,改动也不太大。不过就是http请求多了些,响应慢了些,服务器的负载重了些~
3.2、document.domain+iframe
对于主域相同而子域不同的例子,可以通过设置document.domain的办法来解决。
举www.a.com/a.html和a.com/b.html为例,只需在a.html中添加一个b.html的iframe,并且设置两个页面的document.domain都为'a.com'(只能为主域名),两个页面之间即可互相访问了,代码如下:
www.a.com/a.html中的script
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
document.domain= 'a.com' ;
var ifr = document.createElement( 'iframe' );
ifr.style.display = 'none' ;
document.body.appendChild(ifr); ifr.onload = function (){
//获取iframe的document对象
//W3C的标准方法是iframe.contentDocument,
//IE6、7可以使用document.frames[ID].document
//为了更好兼容,可先获取iframe的window对象iframe.contentWindow
var doc = ifr.contentDocument || ifr.contentWindow.document;
// 在这里操纵b.html
alert(doc.getElementById( "test" ).innerHTML);
}; |
a.com/b.html
1
2
3
4
5
6
7
8
9
10
11
12
|
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> < html >
< head >
< title ></ title >
< script type = "text/javascript" >
document.domain='a.com';
</ script >
</ head >
< body >
< h1 id = "test" >Hello World</ h1 >
</ body >
</ html >
|
如果b.html要访问a.html,可在子窗口(iframe)中通过window.parent来访问父窗口的window对象,然后就可以为所欲为了(window对象都有了,还有啥不行的),同理子窗口也可以和子窗口之间通信。
于是,我们可以通过b.html的XMLHttpRequest来获取数据,再传给a.html,从而解决跨子域获取数据的问题。
但是这种方法只支持同一根域名下的页面,如果不同根域名(例如baidu.com想访问google.com)那就无能为力了。
3.3、动态script标签(Dynamic Script Tag)
这种方法也叫“动态脚本注入”。详情
这种技术克服了XMLHttpRequest的最大限制,也就是跨域请求数据。直接用JavaScript创建一个新的脚本标签,然后设置它的src属性为不同域的URL。
www.a.com/a.html中的script
1
2
3
4
5
|
var dynScript = document.createElement( 'script' );
dynScript.setAttribute( "type" , "text/javascript" );
document.getElementsByTagName( 'head' )[0]
.appendChild(dynScript);
|
通过动态标签注入的必须是可执行的JavaScript代码,因此无论是你的数据格式是啥(xml、json等),都必须封装在一个回调函数中。一个回调函数如下:
www.a.com/a.html中的script
1
2
3
4
|
function dynCallback(data){
//处理数据, 此处简单示意一下
alert(data.content);
} |
在这个例子中,www.b.com/b.js需要将数据封装在上面这个dynCallback函数中,如下:
1
|
dynCallback({content: 'Hello World' })
|
我们看到了让人开心的结果,Hello World~
不过动态脚本注入还是存在不少问题的,下面我们拿它和XMLHttpRequest来对比一下:
XmlHttpRequest Dynamic Script Tag
跨浏览器兼容 | No | Yes |
跨域限制 | Yes | No |
接收HTTP状态 | Yes | No (除了200) |
支持Get、Post | Yes | No (GET only) |
发送、接收HTTP头 | Yes | No |
接收XML | Yes | Yes |
接收JSON | Yes | Yes |
支持同步、异步 | Yes | No (只能异步) |
可以看出,动态脚本注入还是有不少限制,只能使用Get,不能像XHR一样判断Http状态等。
而且使用动态脚本注入的时候必须注意安全问题。因为JavaScript没有任何权限与访问控制的概念,通过动态脚本注入的代码可以完全控制整个页面,所以引入外部来源的代码必须多加小心。
相关推荐
JSONP是一种较早的跨域解决方案,它利用了浏览器允许`<script>`标签跨域加载资源的特性。通过动态创建`<script>`标签,并指定其`src`属性为一个返回JSON数据的函数调用,服务器将数据包裹在函数调用中返回,客户端...
除了资源代理,还可以使用其他跨域解决方案: - CORS(跨源资源共享):服务器端可以设置CORS头(如`Access-Control-Allow-Origin`),允许特定的源进行跨域请求。这种方法需要服务器端的支持,可能不适用于所有...
JavaScript跨域和Ajax跨域是Web开发中常见的问题,尤其在进行前后端分离或API调用时,由于浏览器的同源策略限制,不同域名、协议或端口的资源请求会被阻止,这就是所谓的“跨域”。本文将深入探讨JavaScript和Ajax...
1. **JSONP(JSON with Padding)**:JSONP是一种早期的跨域解决方案,它依赖于`<script>`标签不受同源策略限制的特点。通过动态创建`<script>`标签,设置其`src`属性为提供服务的服务器接口,并由服务器返回一个包裹...
总的来说,jQuery通过JSONP提供了一种简单易用的跨域解决方案,使得前端开发人员能够方便地从不同域名的服务器获取数据,丰富了Web应用的功能。然而,由于JSONP的本质是脚本注入,它可能会带来安全风险,如XSS攻击,...
跨域是指一个域下的文档或脚本尝试请求另一个域下的资源,这是浏览器的一种安全策略,限制了JavaScript的XMLHttpRequest和Fetch API。但有时我们需要在不同的域之间共享数据,这就需要用到CORS机制。 Spring框架...
为了解决这一问题,我们可以采用多种跨域解决方案,其中一种是通过设置代理服务器。 **一、什么是同源策略** 同源策略是浏览器为了保护用户安全而实施的一种安全策略,它规定浏览器只允许加载来自相同协议、域名和...
这个文件可能包含了创建XMLHttpRequest对象、设置请求头、处理响应等内容的JavaScript代码,用于演示如何在实际项目中应用这些跨域解决方案。开发者可以通过查看和运行这些代码来加深对JSONP和CORS的理解,并在自己...
JSONP是一种早期的跨域解决方案,它是通过动态创建`<script>`标签来加载数据的。因为`<script>`标签不受同源策略限制,可以通过`src`属性指向提供JSON数据的外部服务。服务端返回的数据是一个JavaScript函数调用,...
CORS是现代浏览器支持的跨域解决方案。服务器通过设置HTTP响应头`Access-Control-Allow-Origin`来指定允许哪些源进行跨域访问。还可以通过其他响应头如`Access-Control-Allow-Methods`、`Access-Control-Allow-...
4. JSONP(JSON with Padding):这是一种早期的跨域解决方案,适用于只支持GET请求的API。它通过动态创建`<script>`标签来实现跨域请求。然而,JSONP不提供安全性,只适用于简单请求,且不支持HTTP的其他方法和头。...
document.domain + iframe 的设置是一种跨域解决方案。它的原理是设置相同的域名,来实现跨域访问。 ### 4. HTML5 的 postMessage HTML5 的 postMessage 是一种跨域解决方案。它的原理是使用 postMessage 方法来...
本文将深入探讨JavaScript跨域问题及其解决方案,以帮助开发者理解和应对这一问题。 首先,了解同源策略是解决问题的关键。同源策略是浏览器为了保障用户数据安全而实施的一种机制,它禁止了一个源的文档或脚本获取...
2. **JSONP(JSON with Padding)**:JSONP是一种早期的跨域解决方案,主要用于GET请求。它利用`<script>`标签可以跨域加载资源的特性,由服务器提供一个可以接收参数的JavaScript函数,并返回该函数调用的结果。...
另外,`CORS`(Cross-Origin Resource Sharing,跨源资源共享)也是一种广泛使用的跨域解决方案,但主要用于xhr(XMLHttpRequest)和fetch请求。不过,对于`iframe`加载的页面,服务器可以通过设置特定的HTTP响应头`...
CORS 是一种更为灵活且强大的跨域解决方案,它允许服务端通过设置特定的HTTP头部来指定哪些源可以访问其资源。 **原理**: 服务端需要设置`Access-Control-Allow-Origin`头部来允许跨域请求。 **示例**: - 在Node....
“跨域解决方案” 跨域是指一个域下的脚本请求另一个域下的资源。由于浏览器的同源策略限制,会导致跨域请求无法发送。同源策略是指“协议+域名+端口”三者相同,如果两个不同的域名指向同一个 IP 地址也不行,也...
为了解决这些问题,开发者采用了一系列跨域解决方案: 1. JSONP(JSON with Padding)跨域:JSONP是一种利用`<script>`标签不受同源策略限制的特性来实现跨域请求的方法。它通过动态创建`<script>`标签,并设置其`...
1. JSONP(JSON with Padding):JSONP是一种早期的跨域解决方案,它利用了script标签可以跨域加载脚本的特点。服务器返回一个JavaScript函数调用,带有实际的数据作为参数,客户端预先定义好这个函数,从而实现数据...