首先介绍下我的需求:
配置:服务端只有一个Tomcat服务器,Web项目没有用Spring等框架,完全是纯手写Servlet。
项目路径:项目根路径webApps\mainproject,mainproject下有hello文件夹。
域名:主域名myname.com,默认主页是www.myname.com,映射到mainproject\index.jsp,项目中的Servlet等都是该域名下,完成后一切都顺利运行。
然后我想弄一个二级域名hello.myname.com,映射到mainproject\hello\index.jsp。
(如何增加二级域名看这里,如何配置二级域名看这里)
此时,我完成了www.myname.com和hello.myname.com的访问,但是当我正得意时,在hello域名下请求Servlet时提示404找不到,wtf,看了半天才发现请求的url变成了hello.myname.com/Servlet,这要是能请求到那就见鬼了,我的Servlet都是主域名下的,路径不同,肯定访问不到,一想如果直接把url设置成www.myname.com/Servlet不就好了,然后我还是太年轻,报错了,然后就找啊找啊找啊,最后才定位是跨域访问的问题(亏我搜了那么久就没有一个关键字是跨域,所以我才在标题加上二级域名字眼)。好了。废话不多说直接上代码。
再废话一句,想了解跨域是什么的看这里,不想看的直接跳过,或者看完自己项目还有问题的就回来看看我的解决方法。
这是我的ajax请求,这是hello.myname.com主页hello\index.jsp的js请求代码,请求www.myname.com下的CheckServlet。网上很多都说只能用GET不能用POST,但我试了,POST也可以,但是GET肯定可以,dataType必须是jsonp,这个没得说,不理解的看上面跨域的链接
function submit(){
var myName = $("#my_name").val();
var yourName = $("#your_name").val();
$.ajax({
//跨域请求必须是jsop
dataType: 'jsonp',
//请求方式
type:'POST',
//可以自定义,服务端用于接收callback调用的function名的参数,默认是callback
//jsonp : "jsonpCallback"
url:'http://www.myname.com/CheckServlet',
data:{my_name:myName,your_name:yourName},
success: function(data){
var code = data["code"];
if("1" == code){
window.location.href="www.baidu.com";
}else{
alert("error "+code);
}
} ,
error:function(){
alert("error");
}
});
}
js端这样设置就可以了,需要注意的是跨域请求过来的data是json(现在想想是不是可以直接拼字符串,有空试试)。如果你仔细看浏览器的请求就会发现url后面有个callback(不明白callback是什么的可以看上面的跨域链接)
以下是CheckServlet的代码
public class CheckServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
/**
* @see HttpServlet#HttpServlet()
*/
public CheckServlet() {
super();
// TODO Auto-generated constructor stub
}
/**
* @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
*/
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//以下是关键代码,设置允许跨域访问
//允许所有来源访问
response.setHeader("Access-Control-Allow-Origin", "*");
//允许访问的方式
response.setHeader("Access-Control-Allow-Methods", "POST, GET");
response.setContentType("text/html;charset=UTF-8");
//callback是跨域请求的时候生成的,可以自己定义
String callback = request.getParameter("callback");
PrintWriter out = response.getWriter();
String mName = request.getParameter("my_name");
String youName = request.getParameter("your_name");
String code;
if(checkName(mName, youName)){
code = "1";
}else{
code = "0";
}
String outString = "{\"code\":\""+code+"\"}";
//必须要用callback +(返回内容)
out.write(callback+"("+outString+")");
}
private boolean checkName(String myName, String yourName) {
//do your logic
}
/**
* @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
*/
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// TODO Auto-generated method stub
doGet(request, response);
}
}
主要是设置response
//允许所有来源访问
response.setHeader("Access-Control-Allow-Origin", "*");
//允许访问的方式
response.setHeader("Access-Control-Allow-Methods", "POST, GET");
还有数据返回的时候要要用callback拼接(很多博客只介绍了ajax和response设置,导致我没有拼接callbak,每次请求都是error,在此感谢这位博主)
主要三点:
1.ajax请求设置
2.servlet的response设置
3.用callback进行返回值的拼接
好了,到此就就可以开心的玩了。
其实对于二级域名来说我这用的太麻烦,因为hello是在mainproject下,所以如果www.myname.com进入hello路径进行请求的话要么直接使用hello域名要么就重新适配,我为了方便直接将hello.myname.com指向mainproject\hello下了,但最后还是不太方便。
最简单的就是webApps下放多个项目,一个二级域名对应一个项目,这样就避免我上面的嵌套问题,各维护各的,要想访问直接用域名访问。
这就是这两天的成果,完成ajax跨域,以后还是学习用框架吧。