jsjs ajax 跨域访问跨域

JS跨域调用之document.domain--相同基础域名页面之间的调用 - wwwcomy的博客 - ITeye博客
博客分类:
最近项目需要跨域调用JS,整理一下相关知识,写几个帖子记录一下学习历程。
例子只需要1个tomcat即可,这里我的tomcat端口都改成80了。
背景:浏览器在执行Javascript时,出于对安全性的考虑,禁止两个或者多个不同域的页面进行互相操作。
相同域的页面在相互操作的时候不会有任何问题。
如下例子:文件放置于%TOMCAT_HOME%/webapps/domain/目录下
1. parent.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"&
&meta http-equiv="Content-Type" content="text/ charset=utf-8" /&
&title&parent&/title&
// document.domain = "";
function parentFunction() {
alert('function in parent');
function callChild() {
child.window.childFunction();
child 为iframe的name属性值,
不能为id,因为在FireFox下id不能获取iframe对象
&input type="button" name="call child"
value="call child" onclick="callChild()"/&
&br/&&br/&
&!--&iframe name="child" src="/domain/child.html" &--&
&iframe name="child" src="child.html" &
2.child.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"&
&meta http-equiv="Content-Type" content="text/ charset=utf-8" /&
&title&child&/title&
// document.domain = "";
function childFunction() {
alert('function in child');
function callParent() {
parent.parentFunction();
&input type="button" name="call parent" value="call parent" onclick="callParent()"/&
通过localhost/domain/parent.html访问,则可以在子页面和父页面之间相互调用,点击按钮即可看到效果。
接下来我们模拟不用域名的调用,初步我们先处理相同基础域名这个前提下,页面之间的调用,即同顶级域名的不同二级域名之间的调用,如:
/domain/parent.html

/domain/child.html
首先需要修改本地域名映射文件hosts,XP系统此文件地址在C:\WINDOWS\system32\drivers\etc\hosts,win7与linux请google
添加两个域名映射:
127.0.0.1
接下来将parent.html中iframe的src替换为注释的那一段。
此时我们在浏览器中输入/domain/parent.html即可访问到对应页面,这样就可以模拟
与 两个二级域名页面之间的调用了。
如果没有去掉document.domain 这行的注释,浏览器会报错,chrome中的报错信息为
引用Unsafe JavaScript attempt to access frame with URL /domain/child.html from frame with URL /domain/parent.html. Domains, protocols and ports must match.
即不安全的JS调用。
接下来取消注释parent与child页面中的 document.domain 这行代码,发现JS现在可以相互调用了。
注意两个文件都需要这行代码,如果依旧报错请查看是不是由于浏览器的缓存问题。
下面是对document.domain的使用说明和限制条件:
域名必须属于同一个基础域名!而且所用的协议,端口都要一致,否则无法利用document.domain进行跨域
例子中的基础域名就是"",这个域名不能随意指定的,也就是说,如果我们把刚才例子中的document.domain设置为""是会报参数无效的错误的。
通过这种方法,就可以实现同一个基础域名下两个二级域名页面之间JS的跨域相互调用。后面的帖子会介绍其他跨域解决方案。
浏览 14626
浏览: 310159 次
来自: 上海
kulfen 写道你好,1.我照着你的demo 配置运行后,可 ...
kulfen 写道你好,1.我照着你的demo 配置运行后,可 ...
你好,1.我照着你的demo 配置运行后,可以直接访问http ...
lf008 写道你给的demo怎么用,我看了配置里都没配置OA ...
你给的demo怎么用,我看了配置里都没配置OAuth的。用户名:xjsunjie
文章数:1055
评论数:2195
访问量:2811243
注册日期:
阅读量:1297
阅读量:3317
阅读量:450118
阅读量:1134737
51CTO推荐博文
Js跨域问题是web开发人员最常碰到的一个问题之一。所谓js跨域问题,是指在一个域下的页面中通过js访问另一个不同域下的数据对象,出于安全性考 虑,几乎所有浏览器都不允许这种跨域访问,这就导致在一些ajax应用中,使用跨域的web service会成为一个问题。 解决js跨域问题,目前在客户端和服务端都有一些现成的解决方案,但这些方案并不能解决所有问题。下面我们先来看下有哪些常用的解决方案,并针对空间产品 对跨域问题的需求给出一个space自己的解决方案,希望能对其他产品组有借鉴意义。
客户端解决方案
如何在客户端解决js跨域问题几乎是所有web开发人员会首先考虑的。目前最常用的方法有2种:设置document.domain、通过script 标签加载。
设置document.domain
采用这种方法的前提是跨域请求涉及的两个页面必须属于一个基础域(例如都是,或是.cn),使用同一协议(例如都是 http)和同一端口(例如都是80)。例如,里面的一个页面需要调用里的一个对象,则将两个页面的 document.domain都设置为,就可以实现跨域调用了。 另外,需要注意的是,这种方式只能用在父、子页面之中,即只有在用iframe进行数据访问时才有用。
通过script标签加载
对于浏览器来说,script标签的src属性所指向资源就跟img标签的src属性所指向的资源一样,都是一个静态资源,浏览器会在适当的时候自动去加 载这些资源,而不会出现所谓的跨域问题。这样我们就可以通过该属性将要访问的数据对象引用进当前页面而绕过js跨域问题。 例如,在space的我的空间项目中,需要在hi域下管理中心页面中随机推荐几个热门模块给用户,由于热门模块的相关信息都在act域下的php模块中维 护,如果直接在hi域下通过ajax请求去获取act域下的推荐模块列表相关信息就出现js跨域问题。解决这个问题的最简单方法就是,在hi域下通过 script标签去访问act域提供的这个http接口:
&script type=&text/javascript& src=/kf/201109/&http://act./widget/recommend&&&script&
当然,前提是act域的这个http接口必须是返回一段js脚本,如一个json对象数组定义的脚本:
modlist = [
{&modname& : &mod1&,& &usernum& : 200, &url& : & /widget/info/1&},
{&modname& : &mod2&,& &usernum& : 300, &url& : & /widget/info/2&},
但script标签也有一定的局限性,并不能解决所有js跨域问题。script标签的src属性值不能动态改变以满足在不同条件下获取不同数据的需求, 更重要的是,不能通过这种方式正确访问以xml内容方式组织的数据。
服务端解决方案
从上面的说明可以看到,客户端的解决方案局限性太大,而且对于ajax跨域请求,无论两个域是否属于同个基础域,都无法在客户端加以解决。也就是说,如果 我们要想在ajax请求中访问其他域下的数据,就只能通过服务端进行处理了。 服务端的解决方案的基本原理就是,由客户端将请求发给本域服务器,再由本域服务器的代理来请求数据并将响应返回给客户端。 最常用的服务器解决方案就是利用web服务器本身提供的proxy功能,如apache和lighttpd的mod_proxy模块。在百度内 部,transmit的分流功能也可以解决部分跨域问题。但这些方法都有一定的局限性,鉴于安全性等问题的考虑,space这边最后开发了一个专门用于处 理跨域请求代理服务的spproxy模块,用于彻底解决js跨域问题。 下面我们将以空间的开放平台为例,简单介绍下如何通过apache的mod_proxy、transmit的分流以及space的spproxy模块来解 决该跨域问题,并简单介绍下spproxy的一些特性、缺点及下一步的改进计划。 空间在展现每个UWA开放模块之前都必须请求该模块的xml源代码以进行解析,每个模块的源代码文件都是存放在act域下的/ow/uwa目录下,那么在 用户空间首页(hi域)中请求该xml文件时就会存在js跨域问题。要解决该问题,只能让js向hi域的web服务器请求xml文件,而hi域web服务 器则通过一定的代理机制(如mod_proxy、transmit分流、spproxy)向act域的web服务器请求文件。
利用apache的mod_proxy模块
如果apache是2.0系列版本,则可以通过在httpd.conf文件中增加以下配置加以解决:
ProxyRequests& Off
Order deny,allow
Allow from all
ProxyPass& /ow/uwa& http://act./ow/uwa
其中,ProxyRequests 指令关闭了mod_proxy的正向代理功能而启用反向代理功能,Proxy指令使得该配置对所有访问生效,ProxyPass指令使得对本域的/ow /uwa目录下的任何资源的访问都会在内部被转换为一个对act.域下的/ow/uwa目录下对应资源的代理请求。 这样,js就可以直接通过访问/ow/uwa/0/1/0/10001.xml 获取位于act域下的/ow/uwa/0/1/0/目录下的10001.xml文件。
如果apache是经过百度各产品线修改过的1.3版本,则需要mod_proxy和mod_rewrite模块一起配合来达到同样的目的。首先需要在 httpd.conf中增加以下Location指令:
&Location /ow/uwa&
SetHandler proxy-server
order allow,deny
Allow from all
&/Location&
这样,对于本域下的/ow/uwa目录下的任何资源的访问都会首先由proxy-server这个handler(mod_proxy模块内部定义的一个 handler)来处理,但光有这段配置还不行,因为还不proxy-server还不知道应该怎么处理,仅仅知道需要自己处理而已。这时还需要在配置段中增加一个rewrite规则:
RewriteRule ^/ow/uwa/(.*)$& http://act./ow/uwa/$1?%{QUERY_STRING} [P,L]
Rewrite规则最后的[P,L]表明该rewrite是通过mod_proxy代理过去,而不是通过外部重定向过去。如果去掉P标志,即采用以下 rewrite规则:
RewriteRule ^/ow/uwa/(.*)$& http://act./ow/uwa/$1?%{QUERY_STRING} [L]
则响应返回给客户端时标明的资源uri将是重定向后的uri,在我们的例子中就是act.域的uri,则浏览器仍然会出现 js跨 域问题。 以上只是对apache的proxy功能的简单应用,更好更强大的介绍可以参考资料【1】和【2】。 Mod_proxy虽然强大,但我们并没有用它来解决跨域问题。首先,要使用它必须要求我们的每台前端机器都能够访问外网,否则我们就只能将请求代理到其 中一台前端机器上(通过机器名做内网域名进行rewrite或代理),而这显然是不可取的,因为我们的一个域名通常由很多前端机器组成,只代理到其中一台 机器会导致该机器压力与其他机器相比很不均衡,甚至撑不住压力,而给所有前端机器都加访问外网权限又可能会存在一些安全性策略问题(具体原因不清楚,但 op和sa显然是不会赞同这种做法)。其次,由于apache本身并没有很好的防ddos攻击机制,一旦有人通过代理去攻击目标域(比如说我们的竞争对手 的网站),则在目标域的web服务器上看来,攻击者就成了我们了,这样的事情发生时,我们就百口莫辩,跳进黄河也洗不清了。
转自:哈客部落
了这篇文章
类别:┆阅读(0)┆评论(0)还没有任何记录...
前端js跨域请求访问解决方案
作者: 懒人建站
前端js跨域请求访问解决方案有哪些?协议、域名、端口有任何一个不同,都是不同域,同源策略跨域,JSONP跨域(支持get不支持post、postMessage跨域等方法
什么是不同域?
协议、域名、端口有任何一个不同,都被当作是不同的域
什么是跨域?
Web 浏览器具有一个称为相同站点源策略的安全策略,此策略可阻止网页访问另一个域中的数据。 网站通常会让其服务器在后端请求其他站点服务器中的内容,由此避开浏览器中的检查,从而绕开此策略。
注意好多文章写的是&JavaScript出于安全方面的考虑,不允许跨域调用其他页面的对象。& 这根本就是错误的,大家依然在抄来抄去,即使是一些所谓专业前端网站也是直接抄上。
什么是前端跨域?
通过前端方案绕开浏览器的安全策略,在不同的域之间进行数据传输或通信,比如用ajax向一个不同的域请求数据,或者通过js获取页面中不同域的框架(iframe)中的数据。
前端跨域请求访问解决方案有哪些?
同源策略跨域(document.domain)
适用于主域相同而子域不同的情况
具体的做法是在/javascript/kuayu.html和/thread-111.htm两个页面头部&head&区域文件中分别加上&script&document.domain = &&;&/script&
利用iframe和location.hash
使用此方法来完全跨域试试:比如:1.com下的1.com/1.html和2.com域下的2.com/2.html来通讯,来操作一下,
在1.com/1.html加入一个iframe,src=&/2.html&,这样1.com/1.html就可以获取到iframe src上的hash值。
但是浏览器是不允许跨域修改iframe内的跨域域名通过parent.location.hash的值,
所以2.com/2.html并不能通过parent.location.hash修改hash值,这样2.com/2.html有变化是不能通过hash值来通知1.com/1.html,
于是我们要在2.com/2.html里面再加一个iframe src=&/2.html&,然后让src=&/2.html&通过parent.parent.location.hash来修改1.com/1.html那个iframe的hash。
1.com/1.html想知道hash是不是有变化还要加个定时检测,
真的很绕很麻烦,我们还是看看下面还有没有更好的办法吧。
window.name实现的跨域数据传输
有三个页面:
a.com/app.html:应用页面。
a.com/proxy.html:代理文件,一般是一个没有任何内容的html文件,需要和应用页面在同一域下。
b.com/data.html:应用页面需要获取数据的页面,可称为数据页面。
实现起来基本步骤如下:
在应用页面(a.com/app.html)中创建一个iframe,把其src指向数据页面(b.com/data.html)。
数据页面会把数据附加到这个iframe的window.name上,data.html代码如下:
&script type=&text/javascript&&
& & window.name = 'I was there!'; & &// 这里是要传输的数据,大小一般为2M,IE和firefox下可以大至32M左右
& & // 数据格式可以自定义,如json、字符串
在应用页面(a.com/app.html)中监听iframe的onload事件,在此事件中设置这个iframe的src指向本地域的代理文件(代理文件和应用页面在同一域下,所以可以相互通信)。app.html部分代码如下:
&script type=&text/javascript&&
& & var state = 0,&
& & iframe = document.createElement('iframe'),
& & loadfn = function() {
& & & & if (state === 1) {
& & & & & & var data = iframe.contentWindow. & &// 读取数据
& & & & & & alert(data); & &//弹出'I was there!'
& & & & } else if (state === 0) {
& & & & & & state = 1;
& & & & & & iframe.contentWindow.location = &http://a.com/proxy.html&; & &// 设置的代理文件
& & & & } &
& & iframe.src = 'http://b.com/data.html';
& & if (iframe.attachEvent) {
& & & & iframe.attachEvent('onload', loadfn);
& & } else {
& & & & iframe.onload &=
& & document.body.appendChild(iframe);
获取数据以后销毁这个iframe,释放内存;这也保证了安全(不被其他域frame js访问)。
&script type=&text/javascript&&
& & iframe.contentWindow.document.write('');
& & iframe.contentWindow.close();
& & document.body.removeChild(iframe);
总结起来即:iframe的src属性由外域转向本地域,跨域数据即由iframe的window.name从外域传递到本地域。这个就巧妙地绕过了浏览器的跨域访问限制,但同时它又是安全操作。
JSONP跨域(支持get不支持post)
浏览器虽然不让跨域共享数据,但是不限制js资源跨域共享,跨域外链的js是可以执行的,同时也可以获取当前页面上已经。
先看一段代码:
a.com/1.html有如下js:
//回调函数
function callback(data) {
alert(data.message);
&script src=&http://a.com/test.js&&&/script&
a.com/test.js中执行 callback({message:&success&}); a.com/1.html中的函数callback(data)将会被执行,
于是,如果服务端返回一个类似这样的内容,也是可以出现同样的效果。
实际应用:
jqueryz中的$.getJSON
&div id=&images&&&/div&
$.getJSON(&/services/feeds/photos_public.gne?tags=cat&tagmode=any&format=json&jsoncallback=?&, function(data){
$.each(data.items, function(i,item){
$(&&img/&&).attr(&src&, item.media.m).appendTo(&#images&);
if ( i == 3 )
注意jsoncallback=?,服务端返回的函数名就是获取这个参数的值,当然参数名是前后端商定的,函数名就是他传啥就返回啥,因为你的api给别人用还要定死人家的执行的函数名应该是额昂人比较蛋疼的
以php大概演示如下:
$jsondata = json_encode(array('a' =&'b'));
$callback = $_REQUEST['jsoncallback'];
echo &(function(){var _jsonData=$ $callback(_jsonData);})()&;
使用HTML5 postMessage
用postMessage支持基于web的实时消息传递,
浏览器支持情况:Chrome 2.0+、Internet Explorer 8.0+, Firefox 3.0+, Opera 9.6+, 和 Safari 4.0+&
otherWindow.postMessage(message, targetOrigin);
otherWindow: 对接收信息页面的window的引用。可以是页面中iframe的contentWindow属性;window.open的返回值;通过name或下标从window.frames取到的值。
message: 所要发送的数据,string类型。
targetOrigin: 用于限制otherWindow,&*&表示不作限制
</index.html中的代码:
&iframe id=&ifr& src=&/index.html&&&/iframe&
&script type=&text/javascript&&
window.onload = function() {
& & var ifr = document.getElementById(&#39;ifr&#39;);
& & var targetOrigin = &#39;http://b.com&#39;; &// 若写成&#39;http://b.com/c/proxy.html&#39;效果一样
& & & & & & & & & & & & & & & & & & & & // 若写成&#39;http://c.com&#39;就不会执行postMessage了
& & ifr.contentWindow.postMessage(&#39;I was there!&#39;, targetOrigin);
</index.html中的代码:
&script type=&text/javascript&&
& & window.addEventListener(&#39;message&#39;, function(event){
& & & & // 通过origin属性判断消息来源地址
& & & & if (event.origin == &#39;http://a.com&#39;) {
& & & & & & alert(event.data); & &// 弹出&I was there!&
& & & & & & alert(event.source); &// 对a.com、index.html中window对象的引用
& & & & & & & & & & & & & & & & & // 但由于同源策略,这里event.source不可以访问window对象
& & }, false);
CORS(Cross-Origin-Resource-Shares)跨域资源共享(服务端方法)
解决跨域问题,也可以在后端服务器直接设置header内容Access-Contrl-Allow-Origin,
PHP设置CORS:
header(&#39;Access-Control-Allow-Origin: &#39;.$_SERVER[&#39;HTTP_ORIGIN&#39;]);
header(&#39;Access-Control-Allow-Methods: POST, GET, OPTIONS&#39;);
header(&#39;Access-Control-Max-Age: 1000&#39;);
header(&#39;Access-Control-Allow-Headers: Content-Type&#39;);
Apache配置方法:
Header set Access-Control-Allow-Origin * &
以上配置的含义是允许所有的域发起的请求都可以获取该服务器上的资源,当然这样的配置有很大的安全问题,很容易遭受XSS(跨站脚本攻击)。可以只允许某个域访问我们的服务器,如下设置:
Header set Access-Control-Allow-Origin /
对于通配符*,它可以直接Access-Control-Allow-Origin:*这样使用,但它是不允许通配子域名的,如:Access-Control-Allow-Origin:*.
本文链接:/javascript/kuayu.html
前端js跨域请求访问解决方案由懒人建站收集整理,您可以自由传播,请主动带上本文链接
就是免费分享,觉得有用就多来支持一下,没有能帮到您,懒人也只能表示遗憾,希望有一天能帮到您。
(责任编辑:懒人建站)
前端js跨域请求访问解决方案-相关文章
来自百度的搜索推荐js调用接口跨域杂谈
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
作者:杨柳
谈到js跨域调用大家也写过不少,拿php和js为例;跨域大家自己写一般用ajax或loadjson方式。
(许多开源框架有自己的解决方案,如:jquery&,我们暂不讨论。)
再简单罗嗦说下两种方式:
ajax&方式:可同步或异步请求数据。
loadjson&方式&:&接口输出js语句或json数据方式等。
二级域名跨域有时候会用到:
『js』&:&script&type='text/javascript'&document.domain&=&'.cn'&/script&
document.domain&方式缺点不安全。
『php接口』:header('P3P:&CP="CAO&PSA&OUR"');&P3P比较普遍,它有好几个参数值大家可以google下,一般写CAO&PSA&OUR就够用了。
下面说说一级域名跨域,以ajax和loadjson方式来说,个人认为最好用的是loadjson方式,写法方便快捷;ajax方式也可以实现。
下面主要说说闹心的一级域名ajax方式跨域方法:(一般情况不推荐使用,主要是和大家一起了解下该类方法。)
ajax方式一级域名跨域方法说到闹心,因为ajax方式方式写法相对比较麻烦,以前查资料的时候记得好像有2、3种方式,
下面主要说下我用过的一种方法:iframe&跨域取数据;&iframe&方法的主要流程就是&从iframe子页面请求数据,在父页面回调结果操作数据或页面。
还是来个实际例子比较好!&:)
比如我们想从sina的页面下取AAAA的数据:具体步骤如下
首先:在sina&要显示的test.html页面中&添加&&iframe&name="ifm_page"&id="ifm_page"&src="http://event..cn/cooperation/if_Proxy.html"&style="display:none"&onload="window.frames['ifm_page'].get_all_gms();window.frames['ifm_page'].get_hots();"&&onreadystatechange="window.frames['ifm_page'].get_all_gms();window.frames['ifm_page'].get_hots();"&&/iframe&
其中src&中的页面程序进行接口请求。
test.html&部分代码:
//父页面js
window.frames['ifm_page'].get_hots();
//父页面js&回调函数
function&games_hots_Callback()
if&(window.frames["ifm_page"].games_hots.readyState&==&4)
if&(window.frames["ifm_page"].games_hots.status&==&200)
gm_hs=&window.frames["ifm_page"].games_hots.responseText.split("$")[0];
if_Proxy.html&部分代码:
//子页面js
games_hots&=
//if_Proxy&js&函数
function&get_hots()
if(window.XMLHttpRequest)&{
games_hots&=&new&XMLHttpRequest();
if&(games_hots.overrideMimeType)&{
games_hots.overrideMimeType("text/xml");
else&if&(window.ActiveXObject)&{
games_hots&=&new&ActiveXObject("Msxml2.XMLHTTP");
}&catch&(e)&{
games_hots&=&new&ActiveXObject("Microsoft.XMLHTTP");
}&catch&(e)&{}
if&(!games_hots)&{
window.alert("不能创建XMLHttpRequest&对象实例.");
//games_hots.onreadystatechange&=&window.parent.frames["ifm_page"].games_hots_Callback();
games_hots.onreadystatechange&=&parent.games_hots_C&&&&//games_hots_Callback&函数在父页面
var&u&=&encodeURIComponent("/ajax.axd?methodName=GetHotGame");
games_hots.open("POST",&'http://event..cn/cooperation/Proxy.php?action=geturl&uri='&+u,&true);
games_hots.send("");
[&Proxy.php&为调用AAAA相关接口程序处理。]
看了上面代码大家会更明了这种方法【从iframe子页面请求数据,在父页面回调结果操作数据或页面】,这个方法和loadjson比起来确实很麻烦!
要写3个文件,自己产品页面、ifram子页面脚本和请求接口的代理程序接口;了解下这个方式也有好处,联想下跨站取cookie或传值等也可以写个中间代理程序来取。
ajax跨域随笔,请大家多多指教!
已投稿到:
以上网友发言只代表其个人观点,不代表新浪网的观点或立场。}

我要回帖

更多关于 angularjs2 跨域访问 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信