node.js 不允许 POST 请求 - 405 Not Allowed - nginx,即使包含标头

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/24415376/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-02 17:32:44  来源:igfitidea点击:

POST request not allowed - 405 Not Allowed - nginx, even with headers included

node.jsexpressnginxcross-domainnodemailer

提问by debeka

I have a problem in trying to do a POST request in my application and I searched a lot, but I did not find the solution.

我在尝试在我的应用程序中执行 POST 请求时遇到问题,我搜索了很多,但没有找到解决方案。

So, I have a nodeJS application and a website, and I am trying to do a POST request using a form from this site, but I always end up in this:

所以,我有一个 nodeJS 应用程序和一个网站,我正在尝试使用来自该站点的表单来执行 POST 请求,但我总是以这样的方式结束:

enter image description here

在此处输入图片说明

and in the console I see :

在控制台中我看到:

    Uncaught TypeError: Cannot read property 'value' of null 
Post "http://name.github.io/APP-example/file.html " not allowed

that is in this line of code :

在这行代码中:

file.html:

文件.html:

<form id="add_Emails" method ="POST" action="">

    <textarea rows="5" cols="50" name="email">Put the emails here...
    </textarea>

        <p>
        <INPUT type="submit" onclick="sendInvitation()" name='sendInvitationButton' value ='Send Invitation'/>
        </p>


</form>

<script src="scripts/file.js"></script>

file.js:

文件.js:

function sendInvitation(){

    var teammateEmail= document.getElementById("email").value;

I read many post and a documentation of cross domain but it did not work. research source 1:http://enable-cors.org/server.htmlresearch source 2: http://www.w3.org/TR/2013/CR-cors-20130129/#http-access-control-max-age

我阅读了很多帖子和跨域文档,但没有用。研究来源 1:http: //enable-cors.org/server.html研究来源 2:http: //www.w3.org/TR/2013/CR-cors-20130129/#http-access-control-max-年龄

What I am doing now:

我现在在做什么:

I am trying to POST from a different domain of my server :

我正在尝试从我的服务器的不同域进行 POST:

POST REQUEST : http://name.github.io/APP-example/file.html, github repository

POST 请求: http://name.github.io/APP-example/file.html,github 存储库

POST LISTENER : "http://xxx.xxx.x.xx:9000/email, server localhost ( x-> my ip address)

POST LISTENER : " http://xxx.xxx.x.xx:9000/email, server localhost ( x-> my ip address)

So, I had the same problem in other files, but I fixed it putting this code in the begginning of each route:

所以,我在其他文件中遇到了同样的问题,但我修复了它,将这段代码放在每条路线的开头:

var express = require('express');
var sha1 = require('sha1'); 

var router = express.Router(); 
var sessionOBJ = require('./session');

var teams = {} 
var teamPlayers = []

router.all('*', function(req, res, next) {
  res.header("Access-Control-Allow-Origin", "*");
  res.header("Access-Control-Allow-Headers", "X-Requested-With");
  res.header("Access-Control-Allow-Methods", "PUT, GET,POST");
  next();
 });

and I fixed it doing it.

我修复了它。

Now, I am having the same problem, but in this file the only difference is that I deal with SMTP and emails, so I post an email and send an Email to this email I received in the POST request.

现在,我遇到了同样的问题,但在这个文件中唯一的区别是我处理 SMTP 和电子邮件,所以我发布了一封电子邮件并向我在 POST 请求中收到的这封电子邮件发送了一封电子邮件。

THe code is working totally fine with POSTMAN, so, when I test with POSTMAN it works and I can post.

该代码与 POSTMAN 一起工作完全正常,因此,当我使用 POSTMAN 进行测试时,它可以正常工作并且可以发布。

I included this code below instead of the first one I showed but it did not work as well:

我在下面包含了这个代码,而不是我展示的第一个代码,但它不起作用:

router.all('*', function(req, res, next){
            res.header("Access-Control-Allow-Origin", "*")
            res.header("Access-Control-Allow-Methods", "POST, GET, OPTIONS")
            res.header("Access-Control-Allow-Headers", "Origin, Content-Type, Accept")
            res.header("Access-Control-Max-Age", "1728000")
            next();
        });

Does someone know how to solve it?

有人知道如何解决吗?

Thank you.

谢谢你。

回答by Baskar

This configuration to your nginx.conf should help you.

这个配置到你的 nginx.conf 应该对你有帮助。

https://gist.github.com/baskaran-md/e46cc25ccfac83f153bb

https://gist.github.com/baskaran-md/e46cc25ccfac83f153bb

server {
    listen       80;
    server_name  localhost;

    location / {
        root   html;
        index  index.html index.htm;
    }

    error_page  404     /404.html;
    error_page  403     /403.html;

    # To allow POST on static pages
    error_page  405     =200 $uri;

    # ...
}

回答by Indra Uprade

This is the real proxy redirection to the intended server.

这是到目标服务器的真正代理重定向。

server {
  listen          80;
  server_name     localhost;
location / {
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-NginX-Proxy true;
    proxy_pass http://xx.xxx.xxx.xxx/;
    proxy_redirect off;
    proxy_set_header Host $host;

  }
}

回答by jasoos

In my case it was POST submission of a json to be processed and get a return value. I cross checked logs of my app server with and without nginx. What i got was my location was not getting appended to proxy_pass url and the version of HTTP protocol version is different.

就我而言,它是 POST 提交要处理的 json 并获得返回值。我在有和没有 nginx 的情况下交叉检查了我的应用服务器的日志。我得到的是我的位置没有附加到 proxy_pass url 并且 HTTP 协议版本的版本不同。

  • Without nginx: "POST /xxQuery HTTP/1.1" 200 -
  • With nginx: "POST / HTTP/1.0" 405 -
  • 没有 nginx: "POST /xxQuery HTTP/1.1" 200 -
  • 使用 nginx:“POST / HTTP/1.0” 405 -

My earlier location block was

我之前的位置块是

location /xxQuery {
    proxy_method POST;
    proxy_pass http://127.0.0.1:xx00/;
    client_max_body_size 10M;
}

I changed it to

我把它改成

location /xxQuery {
    proxy_method POST;
    proxy_http_version 1.1;
    proxy_pass http://127.0.0.1:xx00/xxQuery;
    client_max_body_size 10M;
}

It worked.

有效。

回答by William Casarin

I noticed this wasn't working with a static-first-then-reverse-proxy setup. Here's what that looks like:

我注意到这不适用于 static-first-then-reverse-proxy 设置。这是它的样子:

location @app {
  proxy_pass http://localhost:3000$request_uri;
}

location / {
  try_files $uri $uri/ @app;
  error_page 405 @app;
}

回答by Siyuan Zhang

I have tried the solution which redirects 405 to 200, and in production environment(in my case, it's Google Load Balancing with Nginx Docker container), this hack causes some 502 errors(Google Load Balancing error code: backend_early_response_with_non_error_status).

我已经尝试了将 405 重定向到 200 的解决方案,并且在生产环境中(在我的例子中,它是带有 Nginx Docker 容器的 Google 负载平衡),这个 hack 会导致一些 502 错误(Google 负载平衡错误代码:backend_early_response_with_non_error_status)。

In the end, I have made this work properly by replacing Nginx with OpenResty which is completely compatible with Nginx and have more plugins.

最后,我通过将 Nginx 替换为与 Nginx 完全兼容并具有更多插件的 OpenResty 使这项工作正常进行。

With ngx_coolkit, Now Nginx(OpenResty) could serve static files with POST request properly, here is the config file in my case:

使用ngx_coolkit,现在 Nginx(OpenResty) 可以正确处理带有 POST 请求的静态文件,这里是我的配置文件:

server {
  listen 80;

  location / {
    override_method GET;
    proxy_pass http://127.0.0.1:8080;
  }
}

server {
  listen 8080;
  location / {
    root /var/www/web-static;
    index index.html;
    add_header Cache-Control no-cache;
  }
}

In the above config, I use override_methodoffered by ngx_coolkitto override the HTTP Method to GET.

在上面的配置中,我使用ngx_coolkitoverride_method提供的将 HTTP 方法覆盖为.GET

回答by SCG

I had similiar issue but only with Chrome, Firefox was working. I noticed that Chrome was adding an Origin parameter in the header request.

我有类似的问题,但只有 Chrome,Firefox 才能正常工作。我注意到 Chrome 在标头请求中添加了一个 Origin 参数。

So in my nginx.conf I added the parameter to avoid it under location/block

所以在我的 nginx.conf 我添加了参数以避免它在location/block 下

proxy_set_header Origin "";