首页 > 解决方案 > Jquery Ajax 对 Nginx 中的静态 html 资源的请求导致“405 不允许”

问题描述

我有一个在 Docker 中运行的带有简单 index.thml 的 Nginx。如果我从带有 http://localhost:8979/index.html 的浏览器调用它,一切正常,但是当我像这样从另一台服务器(https://localhost:8447/)中的 JQuery Ajax 调用它时

 $.ajax({
            type: "GET",
            url: "http://localhost:8979/index.html",
            crossDomain: true,
            success: function (data) {
                $("#myDiv").html(data);
            }
        });

我收到此错误:

从源“https://localhost:8447”访问“http://localhost:8979/index.html”处的 XMLHttpRequest 已被 CORS 策略阻止:对预检请求的响应未通过访问控制检查:没有“访问” -Control-Allow-Origin' 标头存在于请求的资源上。

我的 Nginx 配置是这样的:

server { 
 listen 80;
 location / {
   add_header 'Access-Control-Allow-Origin' '*';
   add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS, DELETE, PUT';
   add_header 'Access-Control-Allow-Headers' 'User-Agent,Keep-Alive,Content-Type'; 
 }
}

我可以在 Devtools 中看到这两个请求:

General
    Request URL: http://localhost:8979/index.html
    Referrer Policy: strict-origin-when-cross-origin
Provisional headers are shown
    Accept: */*
    Access-Control-Allow-Origin: *
    Referer
    sec-ch-ua: "Chromium";v="86", "\"Not\\A;Brand";v="99", "Google Chrome";v="86"
    sec-ch-ua-mobile: ?0
    User-Agent: M
General
    Request URL: http://localhost:8979/index.html
    Request Method: OPTIONS
    Status Code: 405 Not Allowed
    Remote Address: [::1]:8979
    Referrer Policy: strict-origin-when-cross-origin
Response Headers
    Connection: keep-alive
    Content-Length: 559
    Content-Type: text/html
    Date: Thu, 12 Nov 2020 17:54:48 GMT
    Server: nginx/1.19.4
Request Headers
    Accept: */*
    Accept-Encoding: gzip, deflate, br
    Accept-Language: es-ES,es;q=0.9,zh-CN;q=0.8,zh;q=0.7
    Access-Control-Request-Headers: access-control-allow-origin
    Access-Control-Request-Method: GET
    Connection: keep-alive
    Host: localhost:8979
    Origin: https://localhost:8447
    Sec-Fetch-Dest: empty
    Sec-Fetch-Mode: cors
    Sec-Fetch-Site: cross-site
    User-Agent: Mozilla/5.0 (Windows NT 1....

我的 Docker 文件:

FROM nginx
COPY ./nginx.conf /etc/nginx/conf.d/default.conf
COPY ./src/static /usr/share/nginx/html

是 Ajax 请求中的问题还是配置问题?

标签: javascriptjqueryajaxnginxcors

解决方案


试试这个:

map $request_method $options_content_type {
    OPTIONS    "text/plain";
}
map $request_method $options_content_length {
    OPTIONS    0;
}
server { 
    listen 80;
    location / {
        if ($request_method = OPTIONS) { return 204; }
        add_header 'Access-Control-Allow-Origin' '*';
        add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS, DELETE, PUT';
        add_header 'Access-Control-Allow-Headers' 'User-Agent,Keep-Alive,Content-Type'; 
        add_header Content-Type $options_content_type;
        add_header Content-Length $options_content_length;
    }
}

谨防!您将 GET、POST、OPTIONS、DELETE 和 PUT 声明为允许的 HTTP 方法,但实际上除了 GET(现在是 OPTIONS)之外,没有其他方法可以使用此配置。你真的需要所有其他方法吗?


推荐阅读