使用springboot restful 做前后端分离,跨域访问是比较头疼的问题。再解决跨域问题之前,先了解一下什么是同源,什么是跨源资源共享。
同源就是:请求协议一致,请求域名一致,请求端口。在一个浏览器,只能访问同一域名的资源,在当前域名资源中无法访问其他域名资源。例如:
http://www.test.com(目标地址)
http://www.test.com:80 (非同源)
http://www.test.com/test(同源)
https://www.test.com(非同源)
浏览器为了保证其信息安全性,防止恶意网站窃取用户信息,都只提供同源访问。 同源请求给我们开发带来了一定的问题:不能使用ajax请求,dom页面不能访问,cookie不能共享。(参考地址:http://www.ruanyifeng.com/blog/2016/04/cors.html)。为了解决这个问题,w3s提供了CORS( Cross-origin resource sharing 跨域资源共享)规范。详情请参考 http://www.ruanyifeng.com/blog/2016/04/cors.html ,这里就不作解释了。
CORS需要浏览器和服务器同时支持。目前,所有浏览器都支持该功能,IE浏览器不能低于IE10。 总的来说,只要服务端实现了CORS接口,跨域请求就没问题。下面介绍一个基于springboot restful的跨域的请求的列子:
首先新建一个index.html.配置好nginx代理(nginx使用会专门做介绍),实现对静态html的访问。在script写入一下代码:
<script th:inline="javascript">
// 发送CORS请求
//方法1
var url = 'http://localhost:81/get';
var xhr = new XMLHttpRequest();
xhr.onload = function(){ alert(xhr.responseText);};
xhr.open('post', url, true);
xhr.withCredentials = true;//允许获取cookie
// xhr.setRequestHeader('Access-Control-Allow-Origin','');//允许访问的域名
//xhr.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
xhr.send();
}
</script>
或者ajax异步请求:
<script th:inline="javascript">
//方法2.ajax
function makeCorsRequest() {
var url = 'http://localhost:81/get';
var xhr = new XMLHttpRequest();
$.ajax({
// The 'type' property sets the HTTP method.
// A value of 'PUT' or 'DELETE' will trigger a preflight request.
type: 'GET',
// The URL to make the request to.
url: url,
// The 'contentType' property sets the 'Content-Type' header.
// The JQuery default for this property is
// 'application/x-www-form-urlencoded; charset=UTF-8', which does not trigger
// a preflight. If you set this value to anything other than
// application/x-www-form-urlencoded, multipart/form-data, or text/plain,
// you will trigger a preflight request.
contentType: 'text/plain',
xhrFields: {
// The 'xhrFields' property sets additional fields on the XMLHttpRequest.
// This can be used to set the 'withCredentials' property.
// Set the value to 'true' if you'd like to pass cookies to the server.
// If this is enabled, your server must respond with the header
// 'Access-Control-Allow-Credentials: true'.
withCredentials: true
},
headers: {
// Set any custom headers here.
// If you set any non-simple headers, your server must include these
// headers in the 'Access-Control-Allow-Headers' response header.
},
success: function(data) {
// Here's where you handle a successful response.
},
error: function() {
// Here's where you handle an error response.
// Note that if the error was due to a CORS issue,
// this function will still fire, but there won't be any additional
// information about the error.
}
});
}
</script>
springboot对cors有较好的支持,提供了两种使用方法,几乎无需配置即可使用。下面就详情介绍这两种方法:
1.使用注解。在Controller中的处理方法上直接使用注解即可:
@CrossOrigin(origins = "http://localhost")
@GetMapping(value = "/get")
public Object listVouchers() {
return "get";
}
2.自定义配置。上一节讲到添加拦截器时候,我们定义一个类继承WebMvcConfigurerAdapter,我们只要在里面覆盖父类方法即可:
//cors跨域资源分享。设置·跨域请求的路径
@Override
public void addCorsMappings(CorsRegistry registry) {
//告诉springboot,只有get访问路径下的,访问源为localhost的才允许跨域访问
registry.addMapping("/get/**").
allowedOrigins("http://localhost");
}
通过访问http://localhost:8080/index.html。即可成功请求到localhost:81/get.
(参考地址:https://www.html5rocks.com/en/tutorials/cors/)