Jquery Ajax 对 Nginx 中的静态 html 资源的请求导致“405 不允许”

Posted

技术标签:

【中文标题】Jquery Ajax 对 Nginx 中的静态 html 资源的请求导致“405 不允许”【英文标题】:Jquery Ajax request to an static html resource in Nginx causes a "405 Not Allowed" 【发布时间】:2021-02-24 18:33:54 【问题描述】:

我有一个在 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 策略阻止:对预检请求的响应未通过访问控制检查:请求的资源上不存在“Access-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 请求中的问题还是配置问题?

【问题讨论】:

为什么你的 nginx 配置中有两个相同的前缀位置?谁写的?第二个是无用的,永远不会到达,那些标题永远不会设置。将add_header 指令移动到第一个并删除第二个。 感谢您的回答。我删除了它,但问题仍然存在(已编辑) 【参考方案1】:

试试这个:

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)之外,没有其他方法可以使用此配置。您真的需要所有其他方法吗?

【讨论】:

问题是conf文件没有复制到目标文件夹。现在它适用于:server listen 80; location / root /usr/share/nginx/html; index index.html index.htm; 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'; 无论如何,我将回顾那些其他方法。谢谢 @Daniel 该配置不会为OPTIONS HTTP 方法提供 405 Method not allowed 响应(尽管对于成功的 AJAX 请求/响应可能不是严格要求的)。

以上是关于Jquery Ajax 对 Nginx 中的静态 html 资源的请求导致“405 不允许”的主要内容,如果未能解决你的问题,请参考以下文章

jquery ajax nginx 跨域

jquery ajax nginx 跨域

jquery 怎么获取 ajax中的session值

jquery.ajax请求aspx和ashx的异同 Jquery Ajax调用aspx页面方法

Jquery中的ajax

jQuery中的Ajax