`

javascript跨域解决方案(一)

 
阅读更多

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
{}, function(data){
alert('跨域不是越狱:'+data)
}, "html");

结果如下(总之就是不行啦~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.src = 'http://a.com/b.html';
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.src = 'http://www.b.com/b.js';
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没有任何权限与访问控制的概念,通过动态脚本注入的代码可以完全控制整个页面,所以引入外部来源的代码必须多加小心。

分享到:
评论

相关推荐

    Javascript跨域访问解决方案

    JSONP是一种较早的跨域解决方案,它利用了浏览器允许`&lt;script&gt;`标签跨域加载资源的特性。通过动态创建`&lt;script&gt;`标签,并指定其`src`属性为一个返回JSON数据的函数调用,服务器将数据包裹在函数调用中返回,客户端...

    arcgis api for javascript跨域处理方案

    除了资源代理,还可以使用其他跨域解决方案: - CORS(跨源资源共享):服务器端可以设置CORS头(如`Access-Control-Allow-Origin`),允许特定的源进行跨域请求。这种方法需要服务器端的支持,可能不适用于所有...

    Javascript跨域和Ajax跨域解决方案

    JavaScript跨域和Ajax跨域是Web开发中常见的问题,尤其在进行前后端分离或API调用时,由于浏览器的同源策略限制,不同域名、协议或端口的资源请求会被阻止,这就是所谓的“跨域”。本文将深入探讨JavaScript和Ajax...

    js跨域解决方案

    1. **JSONP(JSON with Padding)**:JSONP是一种早期的跨域解决方案,它依赖于`&lt;script&gt;`标签不受同源策略限制的特点。通过动态创建`&lt;script&gt;`标签,设置其`src`属性为提供服务的服务器接口,并由服务器返回一个包裹...

    JQuery跨域访问解决方案

    总的来说,jQuery通过JSONP提供了一种简单易用的跨域解决方案,使得前端开发人员能够方便地从不同域名的服务器获取数据,丰富了Web应用的功能。然而,由于JSONP的本质是脚本注入,它可能会带来安全风险,如XSS攻击,...

    Spring 跨域解决方案官方 demo

    跨域是指一个域下的文档或脚本尝试请求另一个域下的资源,这是浏览器的一种安全策略,限制了JavaScript的XMLHttpRequest和Fetch API。但有时我们需要在不同的域之间共享数据,这就需要用到CORS机制。 Spring框架...

    xmlhttp跨域解决方案

    为了解决这一问题,我们可以采用多种跨域解决方案,其中一种是通过设置代理服务器。 **一、什么是同源策略** 同源策略是浏览器为了保护用户安全而实施的一种安全策略,它规定浏览器只允许加载来自相同协议、域名和...

    跨域请求解决方案源代码(JSONP,CORS)

    这个文件可能包含了创建XMLHttpRequest对象、设置请求头、处理响应等内容的JavaScript代码,用于演示如何在实际项目中应用这些跨域解决方案。开发者可以通过查看和运行这些代码来加深对JSONP和CORS的理解,并在自己...

    Ajax跨域访问解决方案

    JSONP是一种早期的跨域解决方案,它是通过动态创建`&lt;script&gt;`标签来加载数据的。因为`&lt;script&gt;`标签不受同源策略限制,可以通过`src`属性指向提供JSON数据的外部服务。服务端返回的数据是一个JavaScript函数调用,...

    javascript跨域方案总结

    CORS是现代浏览器支持的跨域解决方案。服务器通过设置HTTP响应头`Access-Control-Allow-Origin`来指定允许哪些源进行跨域访问。还可以通过其他响应头如`Access-Control-Allow-Methods`、`Access-Control-Allow-...

    MVC中跨域解决方案

    4. JSONP(JSON with Padding):这是一种早期的跨域解决方案,适用于只支持GET请求的API。它通过动态创建`&lt;script&gt;`标签来实现跨域请求。然而,JSONP不提供安全性,只适用于简单请求,且不支持HTTP的其他方法和头。...

    web跨域解决方案.docx

    document.domain + iframe 的设置是一种跨域解决方案。它的原理是设置相同的域名,来实现跨域访问。 ### 4. HTML5 的 postMessage HTML5 的 postMessage 是一种跨域解决方案。它的原理是使用 postMessage 方法来...

    js 跨域解决方案

    本文将深入探讨JavaScript跨域问题及其解决方案,以帮助开发者理解和应对这一问题。 首先,了解同源策略是解决问题的关键。同源策略是浏览器为了保障用户数据安全而实施的一种机制,它禁止了一个源的文档或脚本获取...

    解决JS跨域访问IFrame的解决方案

    2. **JSONP(JSON with Padding)**:JSONP是一种早期的跨域解决方案,主要用于GET请求。它利用`&lt;script&gt;`标签可以跨域加载资源的特性,由服务器提供一个可以接收参数的JavaScript函数,并返回该函数调用的结果。...

    iframe跨域解决方案

    另外,`CORS`(Cross-Origin Resource Sharing,跨源资源共享)也是一种广泛使用的跨域解决方案,但主要用于xhr(XMLHttpRequest)和fetch请求。不过,对于`iframe`加载的页面,服务器可以通过设置特定的HTTP响应头`...

    前端跨域原理以及跨域解决方案.docx

    CORS 是一种更为灵活且强大的跨域解决方案,它允许服务端通过设置特定的HTTP头部来指定哪些源可以访问其资源。 **原理**: 服务端需要设置`Access-Control-Allow-Origin`头部来允许跨域请求。 **示例**: - 在Node....

    跨域解决方案

    “跨域解决方案” 跨域是指一个域下的脚本请求另一个域下的资源。由于浏览器的同源策略限制,会导致跨域请求无法发送。同源策略是指“协议+域名+端口”三者相同,如果两个不同的域名指向同一个 IP 地址也不行,也...

    前端常见跨域解决方案(全)

    为了解决这些问题,开发者采用了一系列跨域解决方案: 1. JSONP(JSON with Padding)跨域:JSONP是一种利用`&lt;script&gt;`标签不受同源策略限制的特性来实现跨域请求的方法。它通过动态创建`&lt;script&gt;`标签,并设置其`...

    javaScript跨域通信

    1. JSONP(JSON with Padding):JSONP是一种早期的跨域解决方案,它利用了script标签可以跨域加载脚本的特点。服务器返回一个JavaScript函数调用,带有实际的数据作为参数,客户端预先定义好这个函数,从而实现数据...

Global site tag (gtag.js) - Google Analytics