跨域是指从一个域名的网页去请求另外一个域名的资源。好比从http://www.baidu.com/ 页面去请求http://www.google.com 的资源。跨域的严格一点的定义是:只要 协议,域名,端口有任何一个的不一样,就被看成是跨域。 javascript
以下,域名相同的状况下,3000端口的应用没法直接访问8080端口的服务。html
它容许浏览器向跨源服务器,发出XMLHttpRequest
请求,从而克服了AJAX只能同源使用的限制。CORS须要浏览器与服务器的双向支持。整个CORS通讯过程,都是浏览器自动完成,不须要用户参与。对于开发者来讲,CORS通讯与同源的AJAX通讯没有差异,代码彻底同样。浏览器一旦发现AJAX请求跨源,就会自动添加一些附加的头信息,有时还会多出一次附加的请求,但用户不会有感受。所以,实现CORS通讯的关键是服务器。只要服务器实现了CORS接口,就能够跨源通讯。java
在简单的跨域Ajax请求中,会在头部信息中添加Origin参数用于表面这个请求来自哪里,以下react
若是Origin
指定的源,不在许可范围内,服务器会返回一个正常的HTTP回应。浏览器发现,这个回应的头信息没有包含Access-Control-Allow-Origin
字段(详见下文),就知道出错了,从而抛出一个错误,被XMLHttpRequest
的onerror
回调函数捕获。注意,这种错误没法经过状态码识别,由于HTTP回应的状态码有多是200。ios
若是Origin
指定的域名在许可范围内,服务器返回的响应,会多出几个头信息字段,以下:json
其中,几个重要的头信息以下:axios
Origin
字段的值,要么是一个*
,表示接受任意域名的请求。true
,即表示服务器明确许可,Cookie能够包含在请求中,一块儿发给服务器。这个值也只能设为true
,若是服务器不要浏览器发送Cookie,删除该字段便可。如上所述,CORS请求的关键是在后端,即将Origin添加到服务器的许可范围内。在SpringBoot应用中,咱们能够编写一个拦截器,来实现:后端
@Component public class CorsInterceptor implements HandlerInterceptor { @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object o) throws Exception { response.setHeader("Access-Control-Allow-Origin", request.getHeader("Origin")); response.setHeader("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept, If-Modified-Since"); response.setHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS, DELETE"); response.setHeader("Access-Control-Max-Age", "3600"); response.addHeader("Access-Control-Allow-Credentials", "true"); response.setCharacterEncoding("UTF-8"); response.setContentType("application/json"); return true; } @Override public void postHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, ModelAndView modelAndView) throws Exception { } @Override public void afterCompletion(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, Exception e) throws Exception { } }
这里直接容许了全部源,在实际开发中,必须指定可信范围的源。跨域
对于使用creat-react-app构建的项目,能够直接在package.json下配置,具体以下 浏览器
{ "name": "recommender", "version": "0.1.0", "private": true, "proxy": "http://代理地址", "dependencies": { "antd": "^3.23.3", ... }, }
CORS请求默认不发送Cookie和HTTP认证信息。若是要把Cookie发到服务器,一方面要服务器赞成,指定Access-Control-Allow-Credentials为true
。另外一方面,开发者必须在AJAX请求中打开withCredentials
属性。
在Axios中,能够简单设置以下:
import axios from 'axios' //方法1 axios.defaults.withCredentials =true; //方法2 let config = {headers: {'Content-Type': 'multipart-/form-data'},withCredentials: true}; axios.post("http://127.0.0.1:8080/get.do", null, config).then((response) => {alert(response.data)})
服务端的处理,咱们已经在上述代码中实现了,即
response.addHeader("Access-Control-Allow-Credentials", "true");
至此,先后端分离项目便可完成跨域访问与会话保持!