zoukankan      html  css  js  c++  java
  • nginx 实现 ajax 跨域请求Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin

    AJAX从一个域请求另一个域会有跨域的问题。那么如何在nginx上实现ajax跨域请求呢?

    has been blocked by CORS policy: Response to preflight request doesn't pass access control check: The value of the 'Access-Control-Allow-Origin' header in the response must not be the wildcard '*' when the request's credentials mode is 'include'. The credentials mode of requests initiated by the XMLHttpRequest is controlled by the withCredentials attribute.

    要在nginx上启用跨域请求,需要添加add_header Access-Control*指令。如下所示:

    location / {
            add_header         'Access-Control-Allow-Origin' 'https://api.xxxx.com'; 
          add_header      'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
            add_header         "Access-Control-Allow-Credentials" "true";
            add_header         "Access-Control-Allow-Headers" "x-requested-with,content-type";
            proxy_pass         http://localhost:8080;
            proxy_set_header   Host             $host;
            proxy_set_header   X-Real-IP        $remote_addr;
            proxy_set_header   X-Forwarded-For  $proxy_add_x_forwarded_for;
    }

    如果需要允许来自任何域的访问,可以这样配置:

     add_header         'Access-Control-Allow-Origin' '*'; 

    主要是添加了三个用于控制CORS的头信息:

    • Access-Control-Allow-Origin:允许的来源
    • Access-Control-Allow-Credentials:设置为true,允许ajax异步请求带cookie信息
    • Access-Control-Allow-Headers:设置为x-requested-with,content-type,允许ajax余部请求。
    • Access-Control-Allow-Methods GET, POST, OPTIONS :设置指定请求的方法,可以是GET,POST等;

    这个配置也可以在spring mvc里配置。

    问题:

    配置好后,异步跨域请求成功。

    当发起post请求,请求的数据是放在request body里,请求的Content-Type为application/json。Spring MVC需要使用@RequestBody来接收数据。

    这是一次非简单的请求,浏览器会发起一次Options的预请求。发起Options请求报403错误:

    Failed to load https://api.xxxx.com/auth.json: Response to preflight request doesn’t pass access control check: No ‘Access-Control-Allow-Origin’ header is present on the requested resource. Origin ‘https://other.xxxx.com’ is therefore not allowed access. The response had HTTP status code 403.

    解决方法

    原以为是自己的配置有误,但找了很多资料可以确定配置是没有问题。后来debug跟踪Spring MVC DispatcherServlet的调用,发现在DispacerServlet是因为没有找都到执行Options请求的方法。

    在做跨域请求时,配置好CORS相关头信息后,以为就可以了,这很容易忽略在Spring MVC添加对Options请求的处理。

    解决方法有两种:

    • 在拦截器统一添加对Options请求的支持
    • 添加一个支持Options的ReqeuestMapping。

    拦截器示例:

    public class CrosDomainAllowInterceptor implements HandlerInterceptor {
        @Override
        public boolean preHandle(HttpServletRequest request, HttpServletResponse response,
                                 Object handler) throws Exception {
            if(request.getMethod().equals(RequestMethod.OPTIONS.name())) {
                response.setStatus(HttpStatus.OK.value());
                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 {
        }
    }

    @RequestMapping示例

    @RequestMapping(value = "/*",method = RequestMethod.OPTIONS)
    public ResponseEntity handleOptions(){
        return ResponseEntity.noContent();
    }
    愿你眼中有光芒,活成你想要的模样
  • 相关阅读:
    现在分词和过去分词
    VMware Workstation Ubuntu 20.04 LTS无法连接网络问题
    Java中定时器Timer致命缺点(附学习方法)
    2020 年度编程语言排行榜出炉!C 语言称霸,Java 遭遇滑铁卢…….
    人工智能必备数学基础:线性代数基础(1)
    初学VBA
    何同学新视频火了!找到减少沉迷手机的最佳方法:附免费APP
    支付宝蚂蚁森林下线能量提醒功能 产品经理:被骂了、我改
    可抵御所有已知黑客攻击 中国组建天地一体化量子通信网络
    MYSQL数据库 增删改查基础语句
  • 原文地址:https://www.cnblogs.com/SmallStrange/p/13947430.html
Copyright © 2011-2022 走看看