欢迎光临网站排名优化提供专业排名优化轻松提升企业品牌曝光度。

Java Web前后端分离中CORS配置及OPTIONS请求优化

作者:jcmp      发布时间:2021-04-20      浏览量:0
Java Web前后端分离中COR

Java Web前后端分离中CORS配置及OPTIONS请求优化

0x00 CORS 概述

CORS存在的主要原因就是浏览器的同源策略。

预检请求(preflight request)

对于跨域请求,浏览器首先通过OPTIONS方法发送一个预检请求,用于判断服务端是否可以接收当前请求,然后才会发送真正的HTTP请求。

请求头部

在HTTP请求的头部,主要有如下几个字段和CORS相关:

该字段用于标识服务端可以接收来自什么地方的请求,为 "*" 时表示可以接收;

该字段用于标识服务端可以接收什么样的请求,主要包括 GET POST OPTIONS PUT DELETE 等;

该字段存在预检请求中,用于标识服务端允许的头部内容,主要包括 Accept Accept-Language Content-Language Content-Type 等,服务端返回内容到 Access-Control-Expose-Headers 字段;

该字段存在预检请求中,用于标识服务端设置的预检请求信息缓存时间。即在服务端设置的时间范围内,只需发送一次OPTIONS请求;

该字段存在预检请求中,用于标识是否接收浏览器端的认证信息。认证信息主要包括 Cookie authorization headers 等内容。该字段和浏览器中的 withCredentials 相对应,浏览器端用于标识是否发送认证信息,服务端用于标识是否接收认证信息。

0x01 Filter中配置CORS

    @Override    protected boolean preHandle(ServletRequest request, ServletResponse response) throws Exception {        HttpServletRequest httpServletRequest = (HttpServletRequest) request;        HttpServletResponse httpServletResponse = (HttpServletResponse) response;        httpServletResponse.addHeader("Access-Control-Allow-Origin", "path/to/origin");        httpServletResponse            .addHeader("Access-Control-Allow-Methods", "GET, POST, OPTIONS");        httpServletResponse.setHeader("Access-Control-Allow-Headers",            httpServletRequest.getHeader("Access-Control-Request-Headers"));        httpServletResponse.addHeader("Access-Control-Max-Age", "86400");        httpServletResponse.addHeader("Access-Control-Allow-Credentials","false");        if (httpServletRequest.getMethod().equals(RequestMethod.OPTIONS.name())) {            httpServletResponse.setStatus(HttpStatus.OK.value());            return false;        }        return super.preHandle(request, response);    }

0x02 SpringBoot中配置CORS

全局配置

@Configurationpublic class CorsConfig implements WebMvcConfigurer {    @Override    public void addCorsMappings(CorsRegistry registry) {        registry.addMapping("path/to/origin")            .allowedOrigins("*")            .allowedHeaders("*")            .allowedMethods("POST", "GET", "OPTIONS")            .maxAge(86400)            .allowCredentials(false);    }}

单独配置

@CrossOrigin(    origins = "path/to/origin",    methods = {RequestMethod.GET, RequestMethod.POST, RequestMethod.OPTIONS},    allowedHeaders = "*",    allowCredentials = "false",    maxAge = 86400)

0x03 OPTIONS请求优化

右上可知,Access-Control-Max-Age字段用于标识预检请求的缓存时间,因此可以设置Access-Control-Max-Age为较大值来优化OPTIONS请求,在设置的时间段内,只有第一次请求是需要发送OPTIONS的,后面的请求均不需要。

但是,预检请求只针对于单个URL,而不是整个域名,即对 http://domain/a http://domain/b 这2个请求,均需要发送OPTIONS。