文章目录

  • 一、跨域的产生
  • 跨域的原因
  • 二、解决方案
  • 配置跨域
  • 三、options请求是什么鬼?
  • 3.1、为什么会出现options请求呢?
  • 处理微服务开发调试


一、跨域的产生

跨域的原因

跨域是因为浏览器的同源策略限制,是浏览器的一种安全机制,服务端之间是不存在跨域的。
所谓同源指的是两个页面具有相同的协议主机IP端口,三者有任一不相同即会产生跨域。

二、解决方案

配置跨域

/**
 * 跨域配置
 *
 */
@Configuration
public class CorsConfig {
    @Bean
    public CorsWebFilter corsFilter() {
        UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
        CorsConfiguration corsConfiguration = new CorsConfiguration();
        corsConfiguration.addAllowedHeader("*");
        corsConfiguration.addAllowedMethod("*");
        corsConfiguration.addAllowedOriginPattern("*");
        corsConfiguration.setAllowCredentials(true);
        source.registerCorsConfiguration("/**",corsConfiguration);
        return new CorsWebFilter(source);
    }
}

三、options请求是什么鬼?

3.1、为什么会出现options请求呢?

options出现的情况只有两种:

  • 1、获取目的资源所支持的通信方式
  • 2、跨域请求中,options请求是浏览器自发起的preflight request(预检请求),以检测实际请求是否可以被浏览器接受。

preflight request请求报文中有两个需要关注的首部字段:
(1)Access-Control-Request-Method:告知服务器实际请求所使用的HTTP方法;
(2)Access-Control-Request-Headers:告知服务器实际请求所携带的自定义首部字段。

  • 只有复杂请求才会进行preflight request(预检请求)

符合以下任一情况的就是复杂请求

  • 1.使用方法put或者delete;
  • 2.发送json格式的数据(content-type: application/json)
  • 3.请求中带有自定义头部

处理微服务开发调试

GateWay调试场景,开发环境只想启动相应的后端模块接口进行调试,但是因为跨域所以需要每次启动GateWay模块加上模块

spring 跨库 事务 spring跨域解决方案_java

在接口请求中我们总会自定义请求头做token,但是暂浏览器的preflight request(预检请求) 中的OPTIONS只会携带自定义的token字段但不会带相应的值,导致跨域以及报错,
所以要处理跨域以及在SpringSecurity的认证过滤器链中需要过滤掉OPTIONS

  • 上面配了跨域后,再在认证放通即可
  • SpringSecurity的登录认证在放行OPTIONS即可,不然就自己加拦截器放在WebMvcConfig
public void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain)
            throws IOException, ServletException {
        String originalHeader=request.getHeader("Origin");
        if(ObjectUtils.isNotEmpty(originalHeader)){
            response.addHeader("Access-Control-Allow-Origin",originalHeader);
            response.addHeader("Access-Control-Allow-Credentials","true");
            response.addHeader("Access-Control-Allow-Methods","POST,GET,OPTIONS,DELETE,PUT");
            response.addHeader("Access-Control-Allow-Headers",request.getHeader("Access-Control-Request-Headers"));
        }
        if(().equals(request.getMethod())){
            response.setStatus(HttpServletResponse.SC_OK);
            return;
        }
        ...
        }
  • 最后结果
直连本地,其他连接开发环境接口

spring 跨库 事务 spring跨域解决方案_spring boot_02

Access-Control-Allow-Credentials

  • 响应头表示是否可以将对请求的响应暴露给页面。浏览器仅在响应标头Access-Control-Allow-Credentials的值为 true 的情况下将响应暴露给前端的 JavaScript 代码。

Credentials 可以是cookies、authorization headersTLS client certificates

  • 当作为对预检请求的响应的一部分时,这能表示是否真正的请求可以使用 credentials
  • 若一个对资源的请求带了 credentials,如果这个响应头没有随资源返回,响应就会被浏览器忽视,不会返回到 web 内容。
  • Credentials 必须在前后端都被配置(即 Access-Control-Allow-Credentials header 和 XHR 或 Fetch request 中都要配置)才能使带 credentials CORS请求成功。