跨域问题总是很难缠,很多时候开发人员都是不自觉间就遇到了跨域,在此晒晒我的解决之道。
1 避免跨域
在最近一个需求中,有一个网页会出现在两个域名下,开始完全没想到这个问题,导致跨域问题产生,出问题代码如下
<form id="form1" method="post" action="http://www.anotherDomain.com/a.htm?_input_charset=UTF-8">
<input type="hidden" name="action" value="SomeAction"/>
<input type="hidden" name="event_submit_do_something" value="true"/>
......
</form>
<script language="javascript">
myAjax = function(){
myhandle = function (hr){
alert(hr.responseText);
}
YAHOO.util.Connect.asyncRequest(
'POST',
FD.common.getFormAction('form1'),
{
success : myhandle,
failure : myhandle,
timeout : 10000
},
FD.common.formSerialize('form1') + '¶m1='+document.getElementById('param1').value
);
}
</script>
修改方案很简单,采用相对路径
<form id="form1" method="post" action="?_input_charset=UTF-8">
这是最简单的办法,因为本身都是一个页面。在公司框架中,这两种写法,程序最终执行的都是SomeAction中doSomething函数,但是程序发送的请求则有所不同,前者发送到了www.anotherDomain下,后者则在当前的域名下,所以跨域问题也就不存在了。
2 采用jsonp方式
如果你还没听过什么是jsonp,可以先看看http://baike.baidu.com/view/2131174.htm?fr=ala0_1
简单说来,就是采用json方式返回数据,和普通json不同的就是将地址写在script的src属性里欺骗浏览器
为了从另外一个域名下的test.html页面取得一个json数据
var ajaxResult={"count":1};
可以在页面的头部添加这样一句即可
<script src="http://www.anotherdomian.com/test.html?param1=$param1" type="text/javascript"></script>
其中的$param1是由服务器的程序生成,所以每次页面打开后其实$param1是不可变的。就是采用这种方式,页面打开后就可以直接使用ajaxResult这个js的变量了,
3 jsonp方式改进
前一种方法如果说还有什么不好的,那可能就是不够动态吧,下面对第2种方式进行改进。
在http://zhidao.baidu.com/ 未登录用户回答问题时会用iframe调用http://zhidao.baidu.com/userlogin.html
userlogin.html有下面的javascript
<SCRIPT LANGUAGE="JavaScript">
document.domain="baidu.com";
<!--
function G(id){if(typeof(id)=="string"){return document.getElementById(id);}return id;}
function showInfo(obj){
if(obj.checked == true){
G("memInfo").style.display="block";
}else{
G("memInfo").style.display="none";
}
}
function request(id,url){
oScript = document.getElementById(id);
var head = document.getElementsByTagName("head").item(0);
if (oScript) {
head.removeChild(oScript);
}
oScript = document.createElement("script");
oScript.setAttribute("src", url);
oScript.setAttribute("id",id);
oScript.setAttribute("type","text/javascript");
oScript.setAttribute("language","javascript");
head.appendChild(oScript);
return oScript;
}
var loginTimer=null;
var loginState=-1;
var tryTime=0;
function PSP_ik(isOk){
if(isOk==0){
G("errorInfo").style.display="none";
loginState=1;
if(parent.loginSuccess){
parent.Pop.hide();
parent.loginSuccess();
}
}
else
{
loginFalse();
}
}
function loginFalse(){
loginState=0;
var err=G("errorInfo");
err.innerHTML="用户名或密码错误,请重新登录";
err.style.display="block";
G("username").focus();
tryTime++;
if(tryTime>1){
onLoginFailed();
}
}
function onLoginFailed(){
if(parent.onLoginFailed){
parent.Pop.hide();
parent.loginFailed();
}else{
document.login.u.value=escape("http://zhidao.baidu.com/q"+parent.location.search);
doucment.login.submit();
}
}
function loginTimeout(){
if(loginState==-1){
var err=G("errorInfo");
err.innerHTML="操作超时,请重新登录";
err.style.display="block";
G("username").focus();
}
}
function userLogin(){
var username=G('username').value;
var password=G('password').value;
var memPassport=G('memPassport').checked?"on":"off";
if(username.length<=0||password.length<=0){G("username").focus();return false;}
var url = 'https://passport.baidu.com/?logt&tpl=ik&t=0&keyname=ik&mem_pass='+memPassport+'&username='+username + '&loginpass=' +escape(password)+ '&s=' + (new Date()).getTime();
loginState=-1;
var login=request("loginScript",url);
loginTimer = setTimeout(loginTimeout, 5000);
}
window.onload=function(){
document.loginForm.username.focus();
document.getElementById("username").focus();
}
//-->
</SCRIPT>
request方法处理异步请求使用动态往head中添加script而不是用xmlhttp发送get请求。妙就妙在这。我们知道调用javascript是没有域的限制的。当加载完成时一样会执行。
4 通过服务器绕过跨域
将原有的ajax请求,发送到本域名下后台程序,通过后台程序去取得另外一个域名下页面的内容,由于服务器程序不存在跨域的问题,当它得到数据后,再以ajax.responseText返回给原页面,则跨域也可得到解决。
参考文档:
http://baike.baidu.com/view/2131174.htm?fr=ala0_1
http://topic.csdn.net/u/20081224/09/26aff992-d0ba-4f6f-a023-e0e96ecbe1fc.html
分享到:
相关推荐
window.name解决跨域问题的文档,刚才网上发现的.也许有点作用
在本篇文章里小编给各位分享了关于nginx怎么解决跨域问题的方法和实例代码,需要的朋友们参考下。
使用docker部署nginx前后端解决跨域问题
1、地址http://a.test.com:8888/testAjaxCross/public/index.do 演示跨域问题以及跨子域名解决方法 2、地址...演示jsonp解决跨域问题的三种方案jsonp、$getJSON、$ajax等
我使用的是httpClient 进行内部转发 我们在A的服务器上,将前台的文件流,通过httpClient传输到B的服务器上(B的服务器通过控制层接受A传输的文件流,让后保存在B的服务器上。返回一个json结果)
Tomcat lib目录下添加cors-filter-1.7.jar,java-property-utils-1.9.jar这两个jar包,项目中web.xml 中添加filter,以及出现OPTIONS 类型的请求并返回403的解决方案;压缩文件包含jar文件,以及web.xml配置。
### 安装协议解析 跨域处理中间件 koa-body处理post请求数据,也提供了文件上传功能。 @koa/cors解决跨域问题
cors-filter-2.4.jar java-property-utils-1.9.1.jar
在linux 下安装nginx, 解决网页访问时报跨域问题, 只用改配置文件, 亲测有效
sprigboot 完美解决跨域问题和静态资源冲突的demo: final static org.slf4j.Logger logger = org.slf4j.LoggerFactory.getLogger(CorsFilter.class); public void doFilter(ServletRequest req, ServletResponse ...
本资源时整合了spring boot来解决跨域问题:包括 1、设置响应参数解决跨域,2、httpClient解决跨域、3、jsonp解决跨域、4、zuul解决跨域 5、nginx解决跨域
java服务器端解决跨域问题共6页.pdf.zip
关于vue-cli使用本地API代理解决跨域问题的整个流程:包括新建项目到跨域获取数据 关于vue-cli使用本地API代理解决跨域问题的整个流程 关于vue-cli使用本地API代理解决跨域问题的整个流程
本博客中提到的解决跨域问题代码。 下载本文件到本地 方法一: 1.随便打开一个cmd命令窗口 2.输入以下三条命令,即可重新启动chorm 第一句:TASKKILL /F /IM chrome.exe 第二句:start chrome.exe --args --disable-...
框架完美解决了iframe之间的跨域通讯。底层技术采用window.name转换代理实现
亲证可用,真实有效,压缩包里有使用的具体说明,按照要求,绝对可以解决Tomcat的跨域问题
tomcat解决跨域访问问题,具体配置如下: 1、修改tomcat下的Conf/web.xml文件,在该文件内容中新增以下配置,注意,若该web.xml中存在其它filter,则需要将该filter放在所有filter前面; <filter-name>...
php版跨域 ajax+jsonp例子源代码.zip