下面直接帖上网上找到的那篇文章(怕这个链接失效)
来自:
http://hily.me/blog/2006/11/special-domain-data-fetch/。
引用
浏览器跨域获取特定域的数据的办法
以前看了几篇这方面的文章,但是都未能找到一个合适的解决方法。
获取同一个域的数据,可以通过XMLHTTP组件或IFRAME来实现,不存在跨域访问的权限问题,因此比较简单。
但如果要访问不同域的数据时,由于浏览器的安全设置,XMLHTTP没有权限获取数据,而IFRAME没有权限将获取的数据传递给父窗口,似乎没有其它解决办法。
在网上提到的方法,不外乎这两种:
1. 如果要获取的数据位于同一个根域但是不同子域时,可以在脚本中指定document.domain为父域。
2. 如果要获取的数据位于不同的根域时,则可以在服务器上写一个脚本作为代理,由服务器上的脚本获取不同域的数据,然后传递给在同一个域中的网页。
以上两种方法很容易便能想到,现在的问题是,如果要获取一个不同根域的数据时,该如何实现?
一般我们不会漫无目的地去网上获取数据,往往是从指定的服务器上获取数据,就像Google Maps、Google Adsense和referer这样的网页插件,一般都是以脚本的形式提供给用户使用的。这时,如果要求用户在自己的服务器上写个代理的话,易用性就要大打折扣。获取你会考虑为用户写好各种脚本的代理,PHP、ASP、Python、Perl……,但是,如果这台服务器不支持动态脚本,又该怎么办呢?
想了两天都没想通这个问题(除去上班时间其实不到两个小时),曾考虑过用浏览器的漏洞来实现,但是这样做不能长久,因此放弃。随后发现Google本地搜索的地图数据来自于mapabc.com,好家伙,他们是怎么办到的?
用FireFox的DOM查看器可以看到,地图区是一个IFRAME,难道是用IFRAME实现的?但是拖动地图时如何知道要下载哪些图片的?这些数据是一定要从服务器上获取的,难道放这些数据的服务器也是google.com域内的?应该不会这么麻烦。
随即找来Google Maps的API进行开刀,官网给的范例网页如下:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="content-type" content="text/html; charset=utf-8"/>
<title>Google Maps JavaScript API Example</title>
<script src="http://maps.google.com/maps?file=api&v=2&key=abcdefg"
type="text/javascript"></script>
<script type="text/javascript">
//<![CDATA[
function load() {
if (GBrowserIsCompatible()) {
var map = new GMap2(document.getElementById("map"));
map.setCenter(new GLatLng(37.4419, -122.1419), 13);
}
}
//]]>
</script>
</head>
<body onload="load()" onunload="GUnload()">
<div id="map" style="width: 500px; height: 300px"></div>
</body>
</html>
把http://maps.google.com/maps?file=api&v=2&key=abcdefg下载下来看了一下,里面有一句:
GScript("http://maps.google.com/mapfiles/maps2.67.api.js");
这句就是用来加载地图操作库的,GScript函数定义为:
function GScript(src) {document.write('');}
顿悟……
网页内引用不同域的脚本并不会提示权限不足,对了,就是它没错!
这个方法其实我早应该想到的,可能是太久没玩javascript的缘故吧。不论是referer还是Google Analytics,要统计页面访问信息,都要用脚本来向服务器提交信息,只是它们只提交一次(Google Analytics有统计逗留时间,应该有好几次)。习惯性地,我把提交和下载数据分开了,所以不容易想到这个方法。
但是用document.write始终不是好办法,它会清除页面上原有的内容。改进的方法估计你已经想到了,可以参考一下我很早以前乱写的这篇文章《有效地组织页面中复杂的JavaScript脚本》里的思想。
继续分析Google Maps的代码,打开http://maps.google.com/mapfiles/maps2.67.api.js,里面有这样的代码:
ta.prototype.Hk=function(a,b){var c=this.ql(a);if(c){window.setTimeout(function(){b(c)},
0)}else{var d="__cg"+Zf++ +(new Date).getTime();
try{if(this.qe==null){this.qe=document.getElementsByTagName("head")[0]}
var e=window.setTimeout(sd(d,b,a,403),15000);
if(!window.__geoStore){window.__geoStore={}}window.__geoStore[d]=Jf(this,d,b,e);
var f=document.createElement("script");f.type="text/javascript";
f.id=d;f.charset="UTF-8";
f.src=this.vl+"?q="+window.encodeURIComponent(a)+"&output=json&callback=__geoStore."+d+"&key="+this.Lh;
this.qe.appendChild(f)}catch(g){if(e){window.clearTimeout(e)}window.setTimeout(sd(d,
b,a,500),0)}}};
script节点也是动态创建的,这样就可以避免document.write产生的问题。
解决方法找到了,现在来简单测试一下:
1. 在本地服务器上新建一页面。
test.html:
<html>
<head>
<title> Over-Domain Data Fetching Test Page</title>
<script type="text/javascript">
var lastScript;
var h=document.getElementsByTagName("head")[0];</code>
function loadScript(url){
var f=document.createElement("script");
var d=new Date().getTime();
f.type="text/javascript";
f.id=d;
f.src=url+'?'+d;
h.appendChild(f);
if(lastScript&&g(lastScript))g(lastScript).parentNode.removeChild(g(lastScript));
lastScript=d;
}
function g(x){return document.getElementById(x)};
</script>
</head>
<body>
<button onclick="loadScript('http://localhost/alert.js')">Test Alert</button><br />
<button onclick="loadScript('http://localhost/info.js')">Get My Info</button><br />
My Name: <input id="myname" type="text" value="" /><br />
My Blog: <input id="myblog" type="text" value="" />
</body>
</html>
解释两个关键点:
1. lastScript用于存放上次建立的script节点的ID,在下次要再新建script节点时,要删除上次建立的节点,以免加载的脚本越来越多,占用过多的内存。
2. url后面加了一个数值d是为了防止浏览器缓存脚本数据,在本例中可以不加,但是如果脚本是由服务器动态生成的,那最好加上。
然后再建立两个javascript脚本用于测试:
alert.js:
alert('You can see me!');
info.js:
g('myname').value='Hily Jiang';
g('myblog').value='http://hily.iyi.cn/';
好了,把它们放在本地服务器的根目录下,敲入http://127.0.0.1/test.html,这样它和localhost就不在同一个域内了。
点击“Test Alert”,应该会弹出对话框显示You can see me!。
点击“Get My Info”,应该会在文本框中显示我的信息。
(以上测试页在IE 6.0和FireFox1 .5.0下测试通过。)
分享到:
相关推荐
单点登录(Single Sign-On,简称SSO)是一种...这个压缩包可能包含详细的操作指南、示例代码或配置文件,帮助开发者理解和实施SSO跨域iframe通信。实际应用中,需要根据具体的业务需求和技术栈进行适当的调整和优化。
"解决JS跨域访问IFrame的解决方案"这一主题关注的就是如何克服这个限制,使得在JSP页面中嵌入的跨域IFrame能够正常通信。下面我们将详细探讨这个问题以及可能的解决方案。 首先,理解同源策略是关键。同源策略是...
3. **iframe跨域问题**:当iframe加载的页面与包含它的页面不在同一个域时,就会出现跨域问题,导致无法直接通过JavaScript进行通信,如获取iframe内的内容、设置iframe的属性等。 **二、iframe跨域的解决方案** 1...
**解决跨域iframe** 针对`showModalDialog`的跨域问题,一种常见的解决方案是使用`iframe`。`iframe`元素可以嵌入一个外部网页,而且如果目标网页支持CORS(跨源资源共享),则可以在不同的源之间实现数据交互。 **...
知道什么是跨域以及解决跨域的方法,但是具体实际从来没有操作过,直到最近在公司项目中,遇到了一个需要使iframe跨域进行POST提交的实际案例,我才明白具体如何使用iframe进行跨域操作。 说到跨域,就不得不提起...
本篇将深入探讨如何解决`iframe`跨域问题。 首先,我们需要了解`iframe`的基本概念。`iframe`全称 Inline Frame,即内联框架,是一种在HTML文档中嵌入另一个HTML文档的方式,常用于加载外部内容,如广告、地图、...
跨域iframe通信是一种在不同源的页面之间进行数据交换的技术,它主要涉及到浏览器的同源策略。同源策略是浏览器为了安全而实施的一种机制,它限制了来自不同源的JavaScript代码之间的交互,防止恶意网站窃取用户信息...
标题和描述所提及的是一个关于如何解决layer弹窗在跨域环境下的问题,主要涉及到iframe、跨域以及layer的使用技巧。下面我们将详细探讨这个问题及其解决方案。 首先,我们了解下**iframe**。iframe(Inline Frame)...
这种情况下,要想实现跨域iframe大小的自适应,需要采用一些特殊的策略。 解决方案的思路可以分解为以下步骤: 1. 假设有一个页面a.htm属于域A,它通过iframe嵌入了域B下的页面b.html。由于b.html的尺寸可能会变化...
需要将proxy.html放到与内嵌的iframe页同域的服务下, 并且可以被访问到. 使用 支持2种调用方式: 使用 postMessage 和 URL params. postMessage 该方法需要使用 JSON.stringify 将对象转为字符串. // React function...
jQuery提供了一种解决方案,通过利用`postMessage` API来实现跨域iframe接口方法的调用。 同源策略是浏览器安全策略的一部分,它规定只有相同协议、主机名和端口的页面才能相互访问其资源。但在实际应用中,比如...
本文将介绍如何利用location.hash属性来解决跨域iframe自适应高度的问题,同时通过这个方法,我们还可以解决其他相似的跨域JS操作问题。 首先,让我们来了解什么是同源策略和跨域。同源策略要求,如果两个页面拥有...
然而,当`iframe`中的内容来源于不同的源(即跨域)时,会受到浏览器同源策略的限制,这时就需要特殊的处理来解决跨域问题。同时,`iframe`内容的动态加载可能使得其高度不固定,如果不能自适应高度,可能会导致页面...
标题"iframe跨域高度自适应例子源码"指的是一个实例,展示了如何在跨域的情况下使`iframe`内容自动调整高度以适应其内部内容。这个例子提供了一个在线演示(http://okiner.cn/demo/cross-domain/iframe.html)以及源...
本文将详细讲解"PHP main与iframe相互通讯类 同域 跨域"这一主题,以及如何利用提供的文件实现这一功能。 首先,我们要理解同域和跨域的概念。同域是指两个或多个页面的源(协议+域名+端口)相同,它们之间可以自由...
但是,通过特定的技术手段,我们可以实现iframe跨域调用父窗口的JavaScript方法。本教程将详细讲解这一过程。 首先,我们需要了解同源策略。同源策略是浏览器为了保护用户安全而实施的一项机制,它规定只有当两个...
然而,当`iframe`中的页面与包含它的主框架页面位于不同的域名下时,会涉及到跨域安全问题。本文将深入探讨`iframe`与主框架如何进行同域和跨域访问,并提供相关的解决方案。 同域访问: 在同域环境下,即`iframe`...
而跨域则意味着iframe加载的页面与父页面不在同一源下,这就限制了JavaScript对iframe内容的一些操作,包括获取和设置其高度。 解决跨域高度自适应问题的方法通常有两种:一种是使用Window的postMessage API,另一...
这里简单说明两个方法,都是未跨域情况下在index.html内操作b.html内的 DOM。 如:index.html内引入iframe,在index内如何用JS操作iframe内的DOM元素? 先贴下index.html和iframe引入的a.html内容。 index-> &...