解决方案
- 市面上常说的JSONP方式
- 设置请求Header
JSONP方式
JSONP(JSON with Padding)是JSON的一种“使用模式”,可用于解决主流浏览器的跨域数据访问的问题。由于同源策略,一般来说位于 server1.example.com 的网页无法与不是 server1.example.com的服务器沟通,而 HTML 的
<script>
元素是一个例外。利用<script>
元素的这个开放策略,网页可以得到从其他来源动态产生的 JSON 资料,而这种使用模式就是所谓的 JSONP。
由上面的百科解释,其实JSONP能跨域的实质是利用了<script>
的开放策略。像<script>
,<img>
,<link>
等是不受跨域影响的。
view端的代码写法:
<script type="text/javascript">
$(function(){
$.ajax({
url:"http://localhost/data/data/keyData",
type:"get",//请求方式要是get方式
data:"",
dataType:"jsonp",//返回类型要是jsonp而不是json
jsonp: "callback",//回调函数的参数名callback=function
jsonpCallback:"Handler",//回调函数名callback=Handler(可不写,jQuery会生成随机字符串)
success:function(data){
alert(data);
},
error:function(msg){
alert(msg.message);
}
});
});
</script>
服务器端代码写法:
/**
* @param request
* @param response
* @param callback 这个就是从前端传过来的参数名称,按照上面那个写法 这里接收的的值是Handler
*/
@RequestMapping(value="keyData")
@ResponseBody
public void getActivityKeyData(HttpServletRequest request,HttpServletResponse response,String callback){
// listKey 为需要返回的集合对象
List<KeyData> listKey = new ArrayList<KeyData>();
// 这里我们把它转成JSON格式
JSONArray json = JSONArray.fromObject(listKey);
PrintWriter out = null;
try {
out = response.getWriter();
// 这个就是JSONP的重点
// 把数据写出去,写到回调函数的方法里上面穿过来的callback方法
out.write(callback+"("+json+")");
} catch (IOException e) {
e.printStackTrace();
}finally{
if(out!=null){
out.close();
}
}
}
整个JSONP的跨域请求过程重点就是不是直接写出数据,而是写到jQuery的回调函数中。
一般的方式:out.write(json);
现在的方式:out.write(callback+”(“+json+”)”);
Header方式
当你使用XMLHttpRequest发送请求时,浏览器发现该请求不符合同源策略,会给该请求加一个请求头:Origin,后台进行一系列处理,如果确定接受请求则在返回结果中加入一个响应头:Access-Control-Allow-Origin;浏览器判断该相应头中是否包含Origin的值,如果有则浏览器会处理响应,我们就可以拿到响应数据,如果不包含浏览器直接驳回,这时我们无法拿到响应数据。
这种简单粗暴的方式就是直接加响应头部。
view端的代码写法:
<script type="text/javascript">
$(function(){
$.ajax({
url:"http://localhost/data/data/keyData",
type:"post",//请求方式任意
data:"",
dataType:"json",//返回类型任意
success:function(data){
alert(data);
},
error:function(msg){
alert(msg.message);
}
});
});
</script>
这种写法就是ajax正常的请求方式。
服务器端代码写法:
// 设置跨域访问
response.setHeader("Access-Control-Allow-Origin", "*");
response.setHeader("Access-Control-Allow-Method", "POST,GET");
response.setHeader("Access-Control-Max-Age", "3600");
response.setHeader("Access-Control-Allow-Headers", "X-Requested-With");
这种方式不需要需改任何的逻辑代码,只需要在请求方法中设置以上四个响应头部参数就可以。为了方便可以在Filter里设置。
Access-Control-Allow-Origin:允许的跨域请求域名(http://localhost,http://www.xxxxxx.com等)*标示全部。
Access-Control-Allow-Method:允许的请求方式。
Access-Control-Max-Age:超时时间