AJAX跨域解决方法
跨域,简单地理解就是因为浏览器基于安全的同源策略限制不同域名和协议之间的互相访问。
而AJAX的跨域请求,其实浏览器并没有限制不同域的网络请求,只是浏览器会基于请求返回响应头做处理,如果发现是跨域请求且响应头Access-Control-Allow-Origin未对请求来源设置允许,则根据非同源禁止策略,浏览器不会将服务端返回的数据交给AJAX,这样就会阻止不同域之间的数据交互。
介绍两张常用的低廉的解决方案:
1)服务端对访问的来源设置Access-Control-Allow-Origin响应头许可;
此方法不需要javascript做任何改动,只需要服务端层面做处理,相对来说简单易用。
response.setHeader(
"Access-Control-Allow-Origin"
,
"*"
);
感觉这个接口太开放了,不太安全。
如果想只设置自己指定的若干个域名或者端口可以调用接口。
response.addHeader("Access-Control-Allow-Origin","http://a.com,http://b.com");
2)JSONP
jsonp的实现原理,其实就是通过动态加载script标签,预先定义好callback函数处理逻辑,服务端返回的数据其实是一个执行函数的代码,将有效数据作为callback函数的参数。
此方法需要前端和服务端同时做支持,实现成本也比较低廉。
$.ajax({
url:"http://192.168.6.21:8080/jsonp/servlet/Ajax", data:"data=guoyansi", type:"get",dataType:"jsonp",
jsonp:"callbackparam",//传递给请求处理程序或页面的,用以获得jsonp回调函数名的接受 的参数名(默认为callback)
jsonpCallback:"jsonpCallback",// 可选项,写上表示返回函数的函数名用“ jsonpCallback”,不写 默认为jQuery自动生成的随机函数,
error:function(){alert("服务器连接失败");}, success:function(data){ for(var key in data){ alert(key+":"+data[key]); } }});
import net.sf.json.JSONArray;
import net.sf.json.JSONObject; public class Ajax extends HttpServlet { public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doPost(request, response); } public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { response.setContentType("text/plain"); response.setCharacterEncoding("utf-8"); String callbackparam=request.getParameter("callbackparam"); System.out.println("callbackparam:"+callbackparam); String name=request.getParameter("data"); System.out.println("param:"+name); Map<String, String> map=new HashMap<String, String>(); map.put("1", "a"); map.put("2", "b"); map.put("3", "c"); map.put("4", "d"); JSONObject jsonObject=JSONObject.fromObject(map); String result=jsonObject.toString(); PrintWriter writer=response.getWriter();//如果ajax请求写了 jsonpCallback:"jsonpCallback",
writer.write("jsonpCallback("+result+")");//如果ajax请求没有写 jsonpCallback:"jsonpCallback",
writer.write(callbackparam+"("+result+")");//需要callbackparam参数接收随机函数名
}
}
跨域请求,服务端的session会话会被跨域请求覆盖改掉
tomcat使用cookie中jsessionid来区分客户端session会话
跨域请求接口恰恰有时候响应回来会改变服务端的jsessionid值,导致服务器每次判断都是一个新的会话
如果Response 一个cookie值,SET-COOKIE:JSESSIONID=XXXX
服务端,前端刷新一次也没,后端服务会话id都不是同一个sessionid,所有后端所有的请求都是未登录,这就导致前端发送的请求,后端无法拿到当前个人用户信息
服务端部署采用tomcat,所以修改办法是在$TOMCAT_TOME/conf/catalina.properties文件中加上一句,
org.apache.catalina.SESSION_COOKIE_NAME=MYSESSIONID
设置sessionId的cookieName别名,不和默认的jsessionid一直,
最终修改好后,再看服务器的cookie值,服务端使用session取的cookie值是刚刚设置的别名cookie值MYSESSIONID,所以不受跨域接口影响