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

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

0x00 CORS 概述

跨域资源共享(CORS) 是一种机制,它使用额外的 HTTP 头来告诉浏览器 让运行在一个 origin (domain) 上的Web应用被准许访问来自不同源服务器上的指定的资源。当一个资源从与该资源本身所在的服务器不同的域、协议或端口请求一个资源时,资源会发起一个跨域 HTTP 请求

跨域资源共享( CORS )机制允许 Web 应用服务器进行跨域访问控制,从而使跨域数据传输得以安全进行。现代浏览器支持在 API 容器中(例如 XMLHttpRequestFetch )使用 CORS,以降低跨域 HTTP 请求所带来的风险。

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

预检请求(preflight request)

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

请求头部

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

  • Access-Control-Allow-Origin
    

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

  • Access-Control-Allow-Methods
    

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

  • Access-Control-Allow-Headers
    

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

  • Access-Control-Max-Age
    

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

  • Access-Control-Allow-Credentials
    

该字段存在预检请求中,用于标识是否接收浏览器端的认证信息。认证信息主要包括Cookieauthorization 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

全局配置

@Configuration
public 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/ahttp://domain/b这2个请求,均需要发送OPTIONS。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值