一句话概括options预检请求+后端跨域代码解释——打破前后端联调的理解障碍

Posted 砖业洋__

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了一句话概括options预检请求+后端跨域代码解释——打破前后端联调的理解障碍相关的知识,希望对你有一定的参考价值。

最近在看前后端联调的东西,这里梳理一下

  options请求是浏览器的一个机制,不是前端开发人员说不想发options请求就不发的。当你这个post请求跨域的时候,那options请求就出现了(当然还有putdelete请求也会发送预检请求,这些比较少见,我就只谈post)。options请求就去问问浏览器,我想跨域okok?如果后端设置了允许该域名跨域,那么接着post请求就正常发送。否则你就会在控制台看到该请求跨域的错误,类似于下面这种
在这里插入图片描述
  就这么简单,一句话概括:当跨域的时候,post请求之前浏览器就会提前发送options请求,就是询问服务器我能否顺利发送跨域post请求,如果不能,浏览器Console就看到跨域错误提示,如果能,post请求就顺利发送。


  后端配置跨域后,options请求发到服务器,服务器就会返回,但是没有response data,你可以当作是浏览器和服务器的悄悄的对话,不是开发人员手动控制的,因为options也不会命中后端某个接口。

  前端发送POST请求,后端在POST方法里面打断点调试时,也不会阻碍OPTIONS请求的返回
在这里插入图片描述

后端java配置跨域代码一般如下,供参考

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
import org.springframework.web.filter.CorsFilter;

@Configuration
public class CorsConfig {

    public CorsConfig() {
    }

    @Bean
    public CorsFilter corsFilter() {
        // 1. 添加cors配置信息
        CorsConfiguration config = new CorsConfiguration();
        config.addAllowedOrigin("http://localhost:8080");
        // 其实不建议使用*,允许所有跨域
        config.addAllowedOrigin("*");

        // 设置是否发送cookie信息,在前端也可以设置axios.defaults.withCredentials = true;表示发送Cookie,
        // 跨域请求要想带上cookie,必须要请求属性withCredentials=true,这是浏览器的同源策略导致的问题:不允许JS访问跨域的Cookie
        /**
         * withCredentials前后端都要设置,后端是setAllowCredentials来设置
         * 如果后端设置为false而前端设置为true,前端带cookie就会报错
         * 如果后端为true,前端为false,那么后端拿不到前端的cookie,cookie数组为null
         * 前后端都设置withCredentials为true,表示允许前端传递cookie到后端。
         * 前后端都为false,前端不会传递cookie到服务端,后端也不接受cookie
         */
        config.setAllowCredentials(true);

        // 设置允许请求的方式,比如get、post、put、delete,*表示全部
        config.addAllowedMethod("*");

        // 设置允许的header
        config.addAllowedHeader("*");

        // 2. 为url添加映射路径
        UrlBasedCorsConfigurationSource corsSource = new UrlBasedCorsConfigurationSource();
        // /**表示该config适用于所有路由
        corsSource.registerCorsConfiguration("/**", config);

        // 3. 返回重新定义好的corsSource
        return new CorsFilter(corsSource);
    }
}

  后端需要注意的是,我这里设置允许请求的方法是config.addAllowedMethod("*")*表示允许所有HTTP请求方法。如果未设置,则默认只允许“GET”和“HEAD”。你可以设置的HTTPMethodGET, HEAD, POST, PUT, PATCH, DELETE, OPTIONS, TRACE

  经过我的测试,OPTIONS无需手动设置,因为单纯设置OPTIONS也无效。如果你设置了允许POST,代码为config.addAllowedMethod(HttpMethod.POST); 那么其实已经默认允许了OPTIONS,如果你只允许了GET,尝试发送POST请求就会报错如下,预检请求也无法成功响应
在这里插入图片描述
  预检请求返回403,服务器拒绝了OPTIONS类型的请求,因为你只允许了GETOPTIONS类型的请求未被服务器允许。POST请求的状态显示CORS error
在这里插入图片描述

在这里插入图片描述
  有人会疑问了,如果我既设置了GET,又设置了OPTIONS,我能否看到不发送POSTOPTIONS成功返回的场景?

        config.addAllowedMethod(HttpMethod.GET);
        config.addAllowedMethod(HttpMethod.OPTIONS);

  答案是否定的,单纯设置OPTIONS没有意义,现象和上面一样,OPTIONS响应码仍然403POST没有被发送。

  正常情况下我们只要允许了POSTOPTIONS就自动允许了,PUTDELETE也一样。所以从后端开发人员角度来看,无需考虑OPTIONS这种请求,日常需求中POST请求命中接口时根本感知不到OPTIONS请求的存在。


欢迎一键三连~

有问题请留言,大家一起探讨学习

转载请注明:https://blog.csdn.net/qq_34115899/article/details/116763968

----------------------Talk is cheap, show me the code-----------------------

以上是关于一句话概括options预检请求+后端跨域代码解释——打破前后端联调的理解障碍的主要内容,如果未能解决你的问题,请参考以下文章

Spring后端跨域请求设置

为啥我的跨域 POST 请求预检了 OPTIONS 请求?

处理跨域Options预检请求

http跨域预检问题

发送带有自定义 HTTP 标头的跨域请求时禁用预检 OPTION 请求

使用 Spring MVC 4 处理跨域预检 AJAX OPTIONS 请求