现在越来多的地方用到CORS来处理跨域问题,主要还是在于JSONP有一定的条件约束,先看一下对比,本文会介绍包括JSONP和CORS在内的几种解决跨域问题的方式
一、JSONP和CORS 区别
JSONP的原理是动态创建script标签
1.JSONP发送的不是真正的ajax请求
2.JSONP不支持post请求
3.JSONP没有兼容问题
CORS中文意思是跨域资源共享,需要在服务器端设置
cops配置
1.CORS发送的是真正的ajax请求,它允许浏览器向跨源服务器,发出XMLHttpRequest请求,从而克服了AJAX只能同源使用 的限制。
2.CORS既支持get 又支持post
3. CORS需要浏览器和服务器同时支持。目前,所有浏览器都支持该功能,IE浏览器不能低于IE10。
二、JSONP实现跨域原理
JSONP能实现跨域源于其使用了回调函数,整个过程就是前端声明好一个函数,后端返回执行函数。执行函数参数中携带所需的数据,所以要求前后端定义一个回调函数,
1.通过添加一个<script src=""> 来完成一个跨域请求,用于发起跨域请求,后台则把此回调函数返回
前端代码:
//回调函数
function showData (result) {
var data = JSON.stringify(result); //json对象转成字符串
$("#text").val(data);
}
$(document).ready(function () {
$("#btn").click(function () {
//向头部输入一个脚本,该脚本发起一个跨域请求
$("head").append("<script src='http://localhost:8080/test?callback=showData'><\/script>");
});
});
后台代码:
//前端传过来的回调函数名称
String callback = request.getParameter("callback");//前端定义的名称
//用回调函数名称包裹返回数据,这样,返回数据就作为回调函数的参数传回去了
result = callback + "(" + result + ")";
response.getWriter().write(result);
2.通过jquery来实现jsonp跨域请求:
服务端代码不变,js代码如下:
最简单的方式,只需配置一个dataType:'jsonp',就可以发起一个跨域请求。jsonp指定服务器返回的数据类型为jsonp格式,可以看发起的请求路径,自动带了一个callback=xxx,xxx是jquery随机生成的一个回调函数名称。
这里的success就跟上面的showData一样,如果有success函数则默认success()作为回调函数。
<%@ page pageEncoding="utf-8" contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>跨域测试</title>
<script src="js/jquery-1.7.2.js"></script>
<script>
$(document).ready(function () {
$("#btn").click(function () {
$.ajax({
url: "http://localhost:8080/test",
type: "GET",
dataType: "jsonp", //指定服务器返回的数据类型
success: function (data) {
var result = JSON.stringify(data); //json对象转成字符串
$("#text").val(result);
}
});
});
});
</script>
</head>
<body>
<input id="btn" type="button" value="跨域获取数据" />
<textarea id="text" style="width: 400px; height: 100px;"></textarea>
</body>
</html>
三、使用CORS解决跨域问题
在HTML5中有“Cross-Origin Resource Sharing”的新特性,来赋予开发者权力决定资源是否允许被跨域访问。CORS是一个W3C标准,全称是"跨域资源共享"(Cross-origin resource sharing)。它允许浏览器向跨源服务器,发出XMLHttpRequest请求,从而克服了AJAX只能同源使用的限制。整个CORS通信过程,都是浏览器自动完成,不需要用户参与。对于开发者来说,CORS通信与同源的AJAX通信没有差别,代码完全一样。浏览器一旦发现AJAX请求跨源,就会自动添加一些附加的头信息,有时还会多出一次附加的请求,但用户不会有感觉。
因此,实现CORS通信的关键是服务器。只要服务器实现了CORS接口,就可以跨源通信
1.注解方式解决跨域
使用springMVC的注解必须是spring 4.2及以上的版本才支持
@CrossOrigin(origins = "*", maxAge = 3600)
@RestController
@RequestMapping("/test")
public class TestController{
@RequestMapping("/{id}")
public Account retrieve(@PathVariable Long id) {
// DO
}
@RequestMapping(method = RequestMethod.DELETE, path = "/{id}")
public void remove(@PathVariable Long id) {
// DO
}
}
这里指定当前的TestController
中所有的方法可以处理所有域上的请求,当然能加在每一个单独的请求接口之上