如何jquery 解决跨域问题题

本文通过设置Access-Control-Allow-Origin来实现跨域。
例如:客户端的域名是,而请求的域名是。
如果直接使用ajax访问,会有以下错误:
XMLHttpRequest cannot load /server.php. No 'Access-Control-Allow-Origin' header is present on the requested resource.Origin '' is therefore not allowed access.
1、允许单个域名访问
指定某域名()跨域访问,则只需在/server.php文件头部添加如下代码:
header('Access-Control-Allow-Origin:');
2、允许多个域名访问
指定多个域名(、等)跨域访问,则只需在/server.php文件头部添加如下代码:
$origin = isset($_SERVER['HTTP_ORIGIN'])? $_SERVER['HTTP_ORIGIN'] : '';
$allow_origin = array(
if(in_array($origin, $allow_origin)){
header('Access-Control-Allow-Origin:'.$origin);
3、允许所有域名访问
允许所有域名访问则只需在/server.php文件头部添加如下代码:
header('Access-Control-Allow-Origin:*');
记住登录状态
重复输入密码博客分类:
跨域访问是ajax中比较头疼的事情。
Ext的Ext.data.ScriptTagProxy对象是用于解决这个问题的。
这个对象实际上做的事情就是使用动态script标签来处理跨域的请求问题。
script标签的主要优点在于它并不受Web浏览器跨域安全限制的束缚,以及比
XMLHttpRequest具备更好的浏览器兼容性。
ScriptTagProxy的使用方式比较简单,只用在构造函数中设置一个url。
示例代码:
var ds = new Ext.data.Store({
proxy: new Ext.data.ScriptTagProxy({
url: '/forum/topics-remote.php'
reader: new Ext.data.JsonReader({
root: 'topics',
totalProperty: 'totalCount',
id: 'post_id'
{name: 'title', mapping: 'topic_title'},
{name: 'topicId', mapping: 'topic_id'},
{name: 'author', mapping: 'author'},
{name: 'lastPost', mapping: 'post_time', type: 'date', dateFormat: 'timestamp'},
{name: 'excerpt', mapping: 'post_text'}
});
这个url返回的应该是javascript类型的内容,java代码示例:
boolean scriptTag =
String cb = request.getParameter("callback");
if (cb != null) {
scriptTag =
response.setContentType("text/javascript");
response.setContentType("application/x-json");
Writer out = response.getWriter();
if (scriptTag) {
out.write(cb + "(");
out.print(dataBlock.toJsonString());
if (scriptTag) {
out.write(");");
}
ScriptTagProxy会把这段javascript动态添加到页面中,如果javascript中的内容是json格式的,
可以用Ext.data.JsonReader进行解析。
在地址栏中输入
就可以看到ext示例中的返回的javascript内容。
浏览 11133
论坛回复 /
(4 / 6279)
浏览: 100388 次
来自: 天尽头
很好的理解方法,一目了然,怎么书上就不会这样教人理解问题呢?郁 ...
如果表格没有数据怎么显示滚动条啊
呵呵,顶,图片很有意思
少了一种方式
var object = {
我用的是 Ext.Ajax.request ,请问如何实现跨域 ...
(window.slotbydup=window.slotbydup || []).push({
id: '4773203',
container: s,
size: '200,200',
display: 'inlay-fix'博客分类:
使用frame框架解决部分跨域访问问题思路
iframe、frameSet、ifame使用及解决部分跨域访问问题
应用场景:
一个jsp页面中, 嵌套调用了一层ifame;
而这ifame中内嵌的页面,其实对应了一个frameSet, 此frameSet被分割上下两部分: topFrame、 mainFrame
那问题来了:
若在当前页面显示,调用mainFrame中效果:比如显示多级菜单等,就会涉及到跨域访问问题,(top.mainFrame.location.href=XXXX) 等就不能直接做使用了,但是解决的思路也很简单,就是
基本就可以解决问题了!
原因在于,在C/S编程的系统中,可能会有经常使用到类似这种需求,其实就是windows对象下top、parent、self、blank使用不是很清楚。
top、parent、self、blank应用场景
整个浏览器窗口;
parent: 对应父级窗口;
self: 本窗口;
blank: 新窗口。
针对前面的应用场景,其实就是三层的框架嵌套,这里简单解释一下:
若只是一个页面,则 top = parent =
frame嵌套的两层页面,则 top = parent --& self (这里具体看是哪一层,若是第二层,则包含关系; 若第一层,则同i);
针对上面的应用场景,则是三层嵌套的,则 top --& parent --& self(具体看要使用哪一层了)。
解决view页面中跨域访问内嵌页面域值问题
一个可行的方式,是使用给内嵌的frame设置id,然后根据id一路去取,从外到里 或 从里到外 这么来取,还是可行的。
跨域访问,解决session丢失的问题
IE6/IE7支持的P3P(Platform for Privacy Preferences Project (P3P) specification)协议默认阻止第三方无隐私安全声明的cookie,Firefox目前还不支持P3P安全特性,firefox中自然也不存在此问题了。Mircosoft对此的具体描述可以参见 Privacy in Internet Explorer 6.
解决办法是在要嵌入的内容中(iframe指向的站点)输出P3P的主机头声明:
response.setHeader("P3P","CP='IDC DSP COR ADM DEVi TAIi PSA PSD IVAi IVDi CONi HIS OUR IND CNT'") .
zshui_2007
浏览: 13622 次
来自: 上海
(window.slotbydup=window.slotbydup || []).push({
id: '4773203',
container: s,
size: '200,200',
display: 'inlay-fix'由 于此前很少写前端的代码(哈哈,不合格的程序员啊),最近项目中用到json作为系统间交互的手段,自然就伴随着众多ajax请求,随之而来的就是要解决 ajax的跨域问题。本篇将讲述一个小白从遇到跨域不知道是跨域问题,到知道是跨域问题不知道如何解决,再到解决跨域问题,最后找到两种方法解决ajax 跨域问题的全过程。
不知是跨域问题
起 因是这样的,为了复用,减少重复开发,单独开发了一个用户权限管理系统,共其他系统获取认证与授权信息,暂且称之为A系统;调用A系统以B为例。在B系统 中用ajax调用A系统系统的接口(数据格式为json),当时特别困惑,在A系统中访问相应的url可正常回返json数据,但是在B系统中使用 ajax请求同样的url则一点儿反应都没有,好像什么都没有发生一样。这样反反复复改来改去好久都没能解决,于是求救同事,提醒可能是ajax跨域问 题,于是就将这个问题当做跨域问题来解决了。
知跨域而不知如何解决
知道问题的确切原因,剩下的就是找到解决问题的方法了。google了好久,再次在同事的指点下知道jQuery的ajax有jsonp这样的属性可以用来解决跨域的问题。
找到一种解决方式
现在也知道了怎样来解决跨域问题,余下的就是实现的细节了。实现的过程中错误还是避免不了的。由于不了解json和两种格式的区别,也犯了错误,google了好久才解决。
首先来看看在页面中如何使用jQuery的ajax解决跨域问题的简单版:
$(document).ready(function(){
var url='http://localhost:8080/WorkGroupManagment/open/getGroupById"
+"?id=1&callback=?';
dataType:'jsonp',
processData: false,
type:'get',
success:function(data){
alert(data.name);
error:function(XMLHttpRequest, textStatus, errorThrown) {
alert(XMLHttpRequest.status);
alert(XMLHttpRequest.readyState);
alert(textStatus);
这样写是完全没有问题的,起先error的处理函数中仅仅是alert(&error&),为了进一步弄清楚是什么原因造成了错误,故将处理函数变 为上面的实现方式。最后一行alert使用为;parsererror。百思不得其解,继续google,最终还是在万能的stackoverflow找 到了答案,链接在。原因是jsonp的格式与json格式有着细微的差别,所以在server端的代码上稍稍有所不同。
比较一下json与jsonp格式的区别:
json格式:
"message":"获取成功",
"state":"1",
"result":{"name":"工作组1","id":1,"description":"11"}
jsonp格式:
callback({
"message":"获取成功",
"state":"1",
"result":{"name":"工作组1","id":1,"description":"11"}
看出来区别了吧,在url中callback传到后台的参数是神马callback就是神马,jsonp比json外面有多了一层,callback()。这样就知道怎么处理它了。于是修改后台代码。
后台java代码最终如下:
@RequestMapping(value = "/getGroupById")
public String getGroupById(@RequestParam("id") Long id,
HttpServletRequest request, HttpServletResponse response)
throws IOException {
String callback = request.getParameter("callback");
ReturnObject result = null;
Group group = null;
group = groupService.getGroupById(id);
result = new ReturnObject(group, "获取成功", Constants.RESULT_SUCCESS);
} catch (BusinessException e) {
e.printStackTrace();
result = new ReturnObject(group, "获取失败", Constants.RESULT_FAILED);
String json = JsonConverter.bean2Json(result);
response.setContentType("text/html");
response.setCharacterEncoding("utf-8");
PrintWriter out = response.getWriter();
out.print(callback + "(" + json + ")");
return null;
注意这里需要先将查询结果转换我json格式,然后用参数callback在json外面再套一层,就变成了jsonp。指定数据类型为jsonp的ajax就可以做进一步处理了。
虽然这样解决了跨域问题,还是回顾下造成parsererror的原因。原因在于盲目的把json格式的数据当做jsonp格式的数据让ajax处理,造成了这个错误,此时server端代码是这样的:
@RequestMapping(value = "/getGroupById")
@ResponseBody
public ReturnObject getGroupById(@RequestParam("id") Long id,
HttpServletRequest request, HttpServletResponse response){
String callback = request.getParameter("callback");
ReturnObject result = null;
Group group = null;
group = groupService.getGroupById(id);
result = new ReturnObject(group, "获取成功", Constants.RESULT_SUCCESS);
} catch (BusinessException e) {
e.printStackTrace();
result = new ReturnObject(group, "获取失败", Constants.RESULT_FAILED);
至此解决ajax跨域问题的第一种方式就告一段落。
追加一种解决方式
追求永无止境,在google的过程中,无意中发现了一个专门用来解决跨域问题的jQuery插件-。
有第一种方式的基础,使用jsonp插件也就比较简单了,server端代码无需任何改动。
来看一下如何使用jquery-jsonp插件解决跨域问题吧。
var url="http://localhost:8080/WorkGroupManagment/open/getGroupById"
+"?id=1&callback=?";
"url": url,
"success": function(data) {
$("#current-group").text("当前工作组:"+data.result.name);
"error": function(d,msg) {
alert("Could not find user "+msg);
至此两种解决跨域问题的方式就全部介绍完毕。
原文地址:
阅读(...) 评论()JavaScript 跨域总结与解决办法 - 文章 - 伯乐在线
& JavaScript 跨域总结与解决办法
什么是跨域
JavaScript出于安全方面的考虑,不允许跨域调用其他页面的对象。但在安全限制的同时也给注入iframe或是ajax应用上带来了不少麻烦。这里把涉及到跨域的一些问题简单地整理一下:
首先什么是跨域,简单地理解就是因为JavaScript同源策略的限制,a.com 域名下的js无法操作b.com或是域名下的对象。更详细的说明可以看下表:
是否允许通信
同一域名下
/script/b.js
同一域名下不同文件夹
:8000/a.js
同一域名,不同端口
同一域名,不同协议
http://70.32.92.74/b.js
域名和域名对应ip
主域相同,子域不同
http://a.com/b.js
同一域名,不同二级域名(同上)
不允许(cookie这种情况下也不允许访问)
特别注意两点:
第一,如果是协议和端口造成的跨域问题“前台”是无能为力的,
第二:在跨域问题上,域仅仅是通过“URL的首部”来识别而不会去尝试判断相同的ip地址对应着两个域或两个域是否在同一个ip上。
“URL的首部”指window.location.protocol +window.location.host,也可以理解为“Domains, protocols and ports must match”。
接下来简单地总结一下在“前台”一般处理跨域的办法,后台proxy这种方案牵涉到后台配置,这里就不阐述了,有兴趣的可以看看yahoo的这篇文章:《》
1、document.domain+iframe的设置
对于主域相同而子域不同的例子,可以通过设置document.domain的办法来解决。 具体的做法是可以在/a.html和/b.html两个文件中分别加上 document.domain = ‘a.com’;然后通过a.html文件中创建一个iframe,去控制iframe的contentDocument,这样两个js文件之间就可以 “交互”了。当然这种办法只能解决主域相同而二级域名不同的情况,如果你异想天开的把的domian设为 那显然是会报错地!代码如下:
上的a.html
document.domain = 'a.com';
var ifr = document.createElement('iframe');
ifr.src = '/b.html';
ifr.style.display = 'none';
document.body.appendChild(ifr);
ifr.onload = function(){
var doc = ifr.contentDocument || ifr.contentWindow.
// 在这里操纵b.html
alert(doc.getElementsByTagName("h1")[0].childNodes[0].nodeValue);
12345678910
document.domain = 'a.com';var ifr = document.createElement('iframe');ifr.src = '/b.html';ifr.style.display = 'none';document.body.appendChild(ifr);ifr.onload = function(){&&&&var doc = ifr.contentDocument || ifr.contentWindow.document;&&&&// 在这里操纵b.html&&&&alert(doc.getElementsByTagName("h1")[0].childNodes[0].nodeValue);};
上的b.html
document.domain = 'a.com';
document.domain = 'a.com';
这种方式适用于{, , , }中的任何页面相互通信。
备注:某一页面的domain默认等于window.location.hostname。主域名是不带www的域名,例如a.com,主域名前面带前缀的通常都为二级域名或多级域名,例如其实是二级域名。 domain只能设置为主域名,不可以在中将domain设置为。
1、安全性,当一个站点()被攻击后,另一个站点()会引起安全漏洞。
2、如果一个页面中引入多个iframe,要想能够操作所有iframe,必须都得设置相同domain。
2、动态创建script
虽然浏览器默认禁止了跨域访问,但并不禁止在页面中引用其他域的JS文件,并可以自由执行引入的JS文件中的function(包括操作cookie、Dom等等)。根据这一点,可以方便地通过创建script节点的方法来实现完全跨域的通信。具体的做法可以参考YUI的
这里判断script节点加载完毕还是蛮有意思的:ie只能通过script的readystatechange属性,其它浏览器是script的load事件。以下是部分判断script加载完毕的方法。
js.onload = js.onreadystatechange = function() {
if (!this.readyState || this.readyState === 'loaded' || this.readyState === 'complete') {
// callback在此处执行
js.onload = js.onreadystatechange =
js.onload = js.onreadystatechange = function() {&&&&if (!this.readyState || this.readyState === 'loaded' || this.readyState === 'complete') {&&&&&&&&// callback在此处执行&&&&&&&&js.onload = js.onreadystatechange = null;&&&&}};
3、利用iframe和location.hash
这个办法比较绕,但是可以解决完全跨域情况下的脚步置换问题。原理是利用location.hash来进行传值。在url: http://a.com#helloword中的‘#helloworld’就是location.hash,改变hash并不会导致页面刷新,所以可 以利用hash值来进行数据传递,当然数据容量是有限的。假设域名a.com下的文件cs1.html要和域名下的 cs2.html传递信息,cs1.html首先创建自动创建一个隐藏的iframe,iframe的src指向域名下的 cs2.html页面,这时的hash值可以做参数传递用。cs2.html响应请求后再将通过修改cs1.html的hash值来传递数据(由于两个页面不在同一个域下IE、Chrome不允许修改parent.location.hash的值,所以要借助于a.com域名下的一个代理iframe;Firefox可以修改)。同时在cs1.html上加一个定时器,隔一段时间来判断location.hash的值有没有变化,一点有变化则获取获取hash值。代码如下:
先是a.com下的文件cs1.html文件:
function startRequest(){
var ifr = document.createElement('iframe');
ifr.style.display = 'none';
ifr.src = '/lab/cscript/cs2.html#paramdo';
document.body.appendChild(ifr);
function checkHash() {
var data = location.hash ? location.hash.substring(1) : '';
if (console.log) {
console.log('Now the data is '+data);
} catch(e) {};
setInterval(checkHash, 2000);
12345678910111213141516
function startRequest(){&&&&var ifr = document.createElement('iframe');&&&&ifr.style.display = 'none';&&&&ifr.src = '/lab/cscript/cs2.html#paramdo';&&&&document.body.appendChild(ifr);}&function checkHash() {&&&&try {&&&&&&&&var data = location.hash ? location.hash.substring(1) : '';&&&&&&&&if (console.log) {&&&&&&&&&&&&console.log('Now the data is '+data);&&&&&&&&}&&&&} catch(e) {};}setInterval(checkHash, 2000);
<域名下的cs2.html:
//模拟一个简单的参数处理操作
switch(location.hash){
case '#paramdo':
callBack();
case '#paramset':
//do something……
function callBack(){
parent.location.hash = 'somedata';
} catch (e) {
// ie、chrome的安全机制无法修改parent.location.hash,
// 所以要利用一个中间的cnblogs域下的代理iframe
var ifrproxy = document.createElement('iframe');
ifrproxy.style.display = 'none';
ifrproxy.src = 'http://a.com/test/cscript/cs3.html#somedata';
// 注意该文件在"a.com"域下
document.body.appendChild(ifrproxy);
12345678910111213141516171819202122
//模拟一个简单的参数处理操作switch(location.hash){&&&&case '#paramdo':&&&&&&&&callBack();&&&&&&&&break;&&&&case '#paramset':&&&&&&&&//do something……&&&&&&&&break;}&function callBack(){&&&&try {&&&&&&&&parent.location.hash = 'somedata';&&&&} catch (e) {&&&&&&&&// ie、chrome的安全机制无法修改parent.location.hash,&&&&&&&&// 所以要利用一个中间的cnblogs域下的代理iframe&&&&&&&&var ifrproxy = document.createElement('iframe');&&&&&&&&ifrproxy.style.display = 'none';&&&&&&&&ifrproxy.src = 'http://a.com/test/cscript/cs3.html#somedata';&&&&// 注意该文件在"a.com"域下&&&&&&&&document.body.appendChild(ifrproxy);&&&&}}
<下的域名cs3.html
//因为parent.parent和自身属于同一个域,所以可以改变其location.hash的值
parent.parent.location.hash = self.location.hash.substring(1);
//因为parent.parent和自身属于同一个域,所以可以改变其location.hash的值parent.parent.location.hash = self.location.hash.substring(1);
当然这样做也存在很多缺点,诸如数据直接暴露在了url中,数据容量和类型都有限等……
4、window.name实现的跨域数据传输
文章较长列在此处不便于阅读,详细请看 。
5、使用HTML5 postMessage
中最酷的新功能之一就是 。 下一代浏览器都将支持这个功能:Chrome 2.0+、Internet Explorer 8.0+, Firefox 3.0+, Opera 9.6+, 和 Safari 4.0+ 。 Facebook已经使用了这个功能,用postMessage支持基于web的实时消息传递。
otherWindow.postMessage(message, targetOrigin);
otherWindow: 对接收信息页面的window的引用。可以是页面中iframe的contentWindow属性;的返回值;通过name或下标从取到的值。
message: 所要发送的数据,string类型。
targetOrigin: 用于限制otherWindow,“*”表示不作限制
</index.html中的代码:
&iframe id="ifr" src="b.com/index.html"&&/iframe&
&script type="text/javascript"&
window.onload = function() {
var ifr = document.getElementById('ifr');
var targetOrigin = 'http://b.com';
// 若写成'http://b.com/c/proxy.html'效果一样
// 若写成'http://c.com'就不会执行postMessage了
ifr.contentWindow.postMessage('I was there!', targetOrigin);
&iframe id="ifr" src="b.com/index.html"&&/iframe&&script type="text/javascript"&window.onload = function() {&&&&var ifr = document.getElementById('ifr');&&&&var targetOrigin = 'http://b.com';&&// 若写成'http://b.com/c/proxy.html'效果一样&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&// 若写成'http://c.com'就不会执行postMessage了&&&&ifr.contentWindow.postMessage('I was there!', targetOrigin);};&/script&
</index.html中的代码:
&script type="text/javascript"&
window.addEventListener('message', function(event){
// 通过origin属性判断消息来源地址
if (event.origin == 'http://a.com') {
alert(event.data);
// 弹出"I was there!"
alert(event.source);
// 对a.com、index.html中window对象的引用
// 但由于同源策略,这里event.source不可以访问window对象
}, false);
12345678910
&script type="text/javascript"&&&&&window.addEventListener('message', function(event){&&&&&&&&// 通过origin属性判断消息来源地址&&&&&&&&if (event.origin == 'http://a.com') {&&&&&&&&&&&&alert(event.data);&&&&// 弹出"I was there!"&&&&&&&&&&&&alert(event.source);&&// 对a.com、index.html中window对象的引用&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&// 但由于同源策略,这里event.source不可以访问window对象&&&&&&&&}&&&&}, false);&/script&
参考文章:、
6、利用flash
这是从YUI3的IO组件中看到的办法,具体可见。
可以看在Adobe Developer Connection看到更多的跨域代理文件规范:、。
可能感兴趣的话题
alert(document.cookie)
关于伯乐在线博客
在这个信息爆炸的时代,人们已然被大量、快速并且简短的信息所包围。然而,我们相信:过多“快餐”式的阅读只会令人“虚胖”,缺乏实质的内涵。伯乐在线内容团队正试图以我们微薄的力量,把优秀的原创文章和译文分享给读者,为“快餐”添加一些“营养”元素。
新浪微博:
推荐微信号
(加好友请注明来意)
&#8211; 好的话题、有启发的回复、值得信赖的圈子
&#8211; 分享和发现有价值的内容与观点
&#8211; 为IT单身男女服务的征婚传播平台
&#8211; 优秀的工具资源导航
&#8211; 翻译传播优秀的外文文章
&#8211; 国内外的精选文章
&#8211; UI,网页,交互和用户体验
&#8211; 专注iOS技术分享
&#8211; 专注Android技术分享
&#8211; JavaScript, HTML5, CSS
&#8211; 专注Java技术分享
&#8211; 专注Python技术分享
& 2017 伯乐在线}

我要回帖

更多关于 怎么解决跨域问题 的文章

更多推荐

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

点击添加站长微信