AJAX的跨域访问-两种有效的解决方法介绍
程序员文章站
2023-08-18 18:36:41
新的w3c策略实现了http跨域访问,还亏我找了很久的资料解决这个问题:只需要在servlet中返回的头部信息中添加access-control-allow-origin这...
新的w3c策略实现了http跨域访问,还亏我找了很久的资料解决这个问题:
只需要在servlet中返回的头部信息中添加access-control-allow-origin这个既可。
比如我要开放所有我本地的跨域访问,就设置如下:response.setheader("access-control-allow-origin", "http://127.0.0.1/*");
这样我本地的a工程中的ajax请求就可以跨域请求b工程中的servlet。
代码如下:
html的js的ajax请求:
/* create a new xmlhttprequest object to talk to the web server */
var xmlhttp = false;
/*@cc_on @*/
/*@if (@_jscript_version >= 5)
try {
xmlhttp = new activexobject("msxml2.xmlhttp");
} catch (e) {
try {
xmlhttp = new activexobject("microsoft.xmlhttp");
} catch (e2) {
xmlhttp = false;
}
}
@end @*/
if (!xmlhttp && typeof xmlhttprequest != 'undefined') {
xmlhttp = new xmlhttprequest();
}
var url = "http://127.0.0.1:2012/esb/servlet/httpclient?randomtype=mix";
xmlhttp.open("get", url, true);
//setup a function for the server to run when it's done
xmlhttp.onreadystatechange = function(){
if (xmlhttp.readystate == 4) {
var response = xmlhttp.responsetext;
alert(response);
}
}
//send the request
xmlhttp.send(null);
servlet代码:
protected void service(httpservletrequest req, httpservletresponse resp)
throws servletexception, java.io.ioexception {
resp.setheader("pragma", "no-cache");
resp.setheader("cache-control", "no-cache");
//下面那句是核心
resp.setheader("access-control-allow-origin", "http://127.0.0.1/*");
resp.setdateheader("expires", 0);
servletoutputstream sos = resp.getoutputstream();
try {
sos.write(obj.tostring().getbytes("gbk"));
} catch (exception e) {
system.out.println(e.tostring90)
} finally {
try {
sos.close();
} catch (exception e) {
log.error(e);
}
}
}
代码在本机测试是可以的,待过两天,我把servlet放到服务器上去,然后再本地测试。
上面的方式虽然很完美的解决了问题,但是上面的文章也说了。可能存在安全问题,而且新标准是否都支持还是个问题,所以我们可以套用另外一种取巧的方式来完成同样的效果,因为js不存在跨域问题,如果我们服务器的servlet返回的是js脚本,那就可以了。我们可以在a工程的js中使用javascript的src来访问b工程的servlet,然后通过servlet输出的js脚本来传递数据。因此根据这个思想我又做了下面代码的测试:
页面的js代码:
function loadajax(){
id="testesbscript";
oscript = document.getelementbyid(id);
var head = document.getelementsbytagname("head").item(0);
if (oscript) {
head.removechild(oscript);
}
oscript = document.createelement("script");
var url = "http://127.0.0.1:2012/esb/servlet/httpclient?randomtype=mix&success=justhandle
oscript.setattribute("id",id);
oscript.setattribute("type","text/javascript");
oscript.setattribute("language","javascript");
head.appendchild(oscript);
}
//jsuthandle这个函数是反调函数。servlet代码中会使用eval这种方式来执行。
function justhandle(dd){
alert(dd);
}
servlet的代码:
protected void service(httpservletrequest req, httpservletresponse resp)
throws servletexception, java.io.ioexception {
object obj = "test";
servletoutputstream sos = resp.getoutputstream();
stringbuffer sb = new stringbuffer();
resp.setcharacterencoding("gbk");
resp.setheader("charset","gbk");
resp.setcontenttype("charset=gbk");
//下面那句表明是javascript脚本文件
resp.setcontenttype("text/javascript");
sb.append("eval(/""+parammap.get("success")+"(/'"+obj.tostring()+"/')/")");
try {
sos.write(sb.tostring().getbytes(this.character_encoding));
} catch (exception e) {
system.out.println(e.tostring());
} finally {
try {
sos.close();
} catch (exception e) {
system.out.println(e.tostring());
}
}
}
只需要在servlet中返回的头部信息中添加access-control-allow-origin这个既可。
比如我要开放所有我本地的跨域访问,就设置如下:response.setheader("access-control-allow-origin", "http://127.0.0.1/*");
这样我本地的a工程中的ajax请求就可以跨域请求b工程中的servlet。
代码如下:
html的js的ajax请求:
复制代码 代码如下:
/* create a new xmlhttprequest object to talk to the web server */
var xmlhttp = false;
/*@cc_on @*/
/*@if (@_jscript_version >= 5)
try {
xmlhttp = new activexobject("msxml2.xmlhttp");
} catch (e) {
try {
xmlhttp = new activexobject("microsoft.xmlhttp");
} catch (e2) {
xmlhttp = false;
}
}
@end @*/
if (!xmlhttp && typeof xmlhttprequest != 'undefined') {
xmlhttp = new xmlhttprequest();
}
var url = "http://127.0.0.1:2012/esb/servlet/httpclient?randomtype=mix";
xmlhttp.open("get", url, true);
//setup a function for the server to run when it's done
xmlhttp.onreadystatechange = function(){
if (xmlhttp.readystate == 4) {
var response = xmlhttp.responsetext;
alert(response);
}
}
//send the request
xmlhttp.send(null);
servlet代码:
复制代码 代码如下:
protected void service(httpservletrequest req, httpservletresponse resp)
throws servletexception, java.io.ioexception {
resp.setheader("pragma", "no-cache");
resp.setheader("cache-control", "no-cache");
//下面那句是核心
resp.setheader("access-control-allow-origin", "http://127.0.0.1/*");
resp.setdateheader("expires", 0);
servletoutputstream sos = resp.getoutputstream();
try {
sos.write(obj.tostring().getbytes("gbk"));
} catch (exception e) {
system.out.println(e.tostring90)
} finally {
try {
sos.close();
} catch (exception e) {
log.error(e);
}
}
}
代码在本机测试是可以的,待过两天,我把servlet放到服务器上去,然后再本地测试。
上面的方式虽然很完美的解决了问题,但是上面的文章也说了。可能存在安全问题,而且新标准是否都支持还是个问题,所以我们可以套用另外一种取巧的方式来完成同样的效果,因为js不存在跨域问题,如果我们服务器的servlet返回的是js脚本,那就可以了。我们可以在a工程的js中使用javascript的src来访问b工程的servlet,然后通过servlet输出的js脚本来传递数据。因此根据这个思想我又做了下面代码的测试:
页面的js代码:
复制代码 代码如下:
function loadajax(){
id="testesbscript";
oscript = document.getelementbyid(id);
var head = document.getelementsbytagname("head").item(0);
if (oscript) {
head.removechild(oscript);
}
oscript = document.createelement("script");
var url = "http://127.0.0.1:2012/esb/servlet/httpclient?randomtype=mix&success=justhandle
oscript.setattribute("id",id);
oscript.setattribute("type","text/javascript");
oscript.setattribute("language","javascript");
head.appendchild(oscript);
}
//jsuthandle这个函数是反调函数。servlet代码中会使用eval这种方式来执行。
function justhandle(dd){
alert(dd);
}
servlet的代码:
复制代码 代码如下:
protected void service(httpservletrequest req, httpservletresponse resp)
throws servletexception, java.io.ioexception {
object obj = "test";
servletoutputstream sos = resp.getoutputstream();
stringbuffer sb = new stringbuffer();
resp.setcharacterencoding("gbk");
resp.setheader("charset","gbk");
resp.setcontenttype("charset=gbk");
//下面那句表明是javascript脚本文件
resp.setcontenttype("text/javascript");
sb.append("eval(/""+parammap.get("success")+"(/'"+obj.tostring()+"/')/")");
try {
sos.write(sb.tostring().getbytes(this.character_encoding));
} catch (exception e) {
system.out.println(e.tostring());
} finally {
try {
sos.close();
} catch (exception e) {
system.out.println(e.tostring());
}
}
}