首先介绍下我的需求:
配置:服务端只有一个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跨域,以后还是学习用框架吧。