• 【跨域】SpringBoot跨域,拦截器中,第一次获取的请求头为NULL,发送两次请求的处理方式


    背景:

    在做前后端分离时,牵扯到跨域,但是已经设置了跨域
    前端设置了允许携带Cookie
    axios.defaults.withCredentials = true;
    后端也配置了跨域

    浏览器端查看发送的请求,请求头中包含Authorization



    原因:

    实际上发送了两次请求,第一次为OPTIONS请求,第二次才GET/POST...请求

    • OPTIONS请求中,不会携带请求头的参数,所以在拦截器上获取请求头为空,自定义的拦截器拦截成功
    • 第一次请求不能通过,就不能获取第二次的请求了GET/POST...
    • 第一次请求不带参数,第二次请求才带参数

    解决:

    在拦截器中,如果请求为OPTIONS请求,让 OPTIONS 请求返回一个200状态码,表示可以正常访问,然后就会收到真正的GET/POST请求

    String method = request.getMethod();	//输出 OPTIONS/GET/POST。。。
    //如果是 OPTIONS 请求,让 OPTIONS 请求返回一个200状态码
    if (HttpMethod.OPTIONS.toString().equals(request.getMethod())) {
        response.setStatus(HttpServletResponse.SC_OK);
        return false;
    }
    



    拦截器完整示例

    @Component
    public class HttpRequestInterceptor implements HandlerInterceptor {
        @Override
        public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
            //origin:指定可以访问本项目的IP
            String origin = request.getHeader("Origin");
            response.setContentType("application/json;charset=UTF-8");
            response.setHeader("Access-Control-Allow-Origin", origin);
            response.setHeader("Access-Control-Allow-Methods", "POST, GET, PUT, OPTIONS, DELETE");
            response.setHeader("Access-Control-Max-Age", "1800");
            //  设置  受支持请求标头(自定义  可以访问的请求头  例如:Token)
            response.setHeader("Access-Control-Allow-Headers", "x-requested-with,Authorization,token,Origin,Content-Type,Accept");
            // 指示的请求的响应是否可以暴露于该页面。当true值返回时它可以被暴露
            response.setHeader("Access-Control-Allow-Credentials", "true");
            //如果是OPTIONS请求,让其响应一个 200状态码,说明可以正常访问
            if (HttpMethod.OPTIONS.toString().equals(request.getMethod())) {
                response.setStatus(HttpServletResponse.SC_OK);
                return false;
            }
            return true;
        }
    
        @Override
        public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
        }
    
        @Override
        public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        }
    }
    

    配置拦截器

    自定义的拦截器必须要配置,才能使用

    @Configuration
    public class WebConfig implements WebMvcConfigurer {
    
    	@Autowired
        private HttpRequestInterceptor httpRequestInterceptor;
        
        // 配置拦截器
        @Override
        public void addInterceptors(InterceptorRegistry registry) {
            //设置跨域得拦截器 ,/** 表示拦截所有请求
            registry.addInterceptor(httpRequestInterceptor).addPathPatterns("/**");
        }
    }
    
    
    为天地立心,为生民立命,为往圣继绝学,为万世开太平。
  • 相关阅读:
    解决Spring MVC无法接收AJAX使用PUT与DELETE请求传输的内容
    js中定时器setTimeout与setInterval使用方法经验总结
    解决ajax请求(SpringMVC后台)响应415/400/405错误
    css3 calc()的用法
    echarts2 饼图处理标签文字过长使之达到指定字数换行的目的
    在webstorm开发微信小程序之使用阿里自定义字体图标
    webstorm的一些小技巧
    前端 一些小知识,技巧总结
    用webstorm来开发微信小程序之less的配置
    js,mui,jq 操作基本的DOM
  • 原文地址:https://www.cnblogs.com/rxx1005/p/12781797.html
Copyright © 2020-2023  润新知