不允许 POST 请求 - 405 不允许 - nginx,即使包含标头

问题描述 投票:0回答:9

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

所以,我有一个 NodeJS 应用程序和一个网站,我尝试使用此网站中的表单执行 POST 请求,但我总是以这种方式结束:

enter image description here

在控制台中我看到:

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

就是这行代码:

文件.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>

文件.js:

function sendInvitation(){

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

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

我现在在做什么:

我正在尝试从我的服务器的不同域发布:

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

POST监听器:“http://xxx.xxx.x.xx:9000/email,服务器本地主机(x->我的IP地址)

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

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();
 });

我修复了它。

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

代码在 POSTMAN 中工作得很好,所以,当我用 POSTMAN 测试时,它可以工作并且我可以发布。

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

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();
        });

有人知道如何解决吗?

谢谢你。

node.js express nginx cross-domain nodemailer
9个回答
67
投票

您的 nginx.conf 的此配置应该对您有所帮助。

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;

    # ...
}

6
投票

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

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;

  }
}

4
投票

我注意到这不适用于先静态后反向代理设置。看起来像这样:

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

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

2
投票

在我的例子中,是 POST 提交要处理的 json 并获取返回值。我交叉检查了使用和不使用 nginx 的应用程序服务器的日志。我得到的是我的位置没有附加到 proxy_pass url 并且 HTTP 协议版本不同。

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

我之前的位置块是

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

我把它改成了

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

成功了。


1
投票

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

最后,我用 OpenResty 替换 Nginx,使这个工作正常进行,OpenResty 与 Nginx 完全兼容,并且有更多的插件。

使用 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;
  }
}

在上面的配置中,我使用

ngx_coolkit
提供的 override_method 将 HTTP 方法覆盖为
GET


0
投票

我在使用 VueJs 作为托管在

example.com
的前端应用程序时遇到了类似的问题,而我的 Rails 应用程序作为托管在
api.example.com
的 API。 Vue 配置为通过
ENV
变量
VUE_APP_API_BASE_URL
获取数据。

我犯了一个菜鸟错误,忘记在生产服务器上创建

env.production.local
,因此在构建 VueJs 应用程序时,从未获取过 url。因此,所有请求都被路由到例如
example.com/signin
而不是
api.example.com/signin
,因此出现错误。

在生产服务器上创建文件并添加变量,然后重新构建 vuejs 应用程序后,一切正常!


0
投票

已经太晚了,但如果有人遇到这个问题,请在 nginx.conf 中添加以下代码

server {

        ...

        # pass PHP scripts to FastCGI server
        #
        location ~ \.php$ {
                include snippets/fastcgi-php.conf;

                # With php-fpm (or other unix sockets):
                fastcgi_pass unix:/var/run/php/php7.4-fpm.sock;
                # With php-cgi (or other tcp sockets):

        }


}

0
投票

嘿,我也遇到了这个问题,这是我发现的唯一可行的解决方案(无需破解 405 页面)
我假设问题出在 POST 请求上。
正如其他一些人指出的那样,您不仅可以通过发布请求将数据转发到其他端点。在没有任何插件的情况下解决这个问题的非黑客方法是使用重写方法。基本上,此方法所做的只是重写 URL 的一部分,但它还有一个特性,即不会在 POST 请求上抛出 405。

location /api/ {
    # Removes the /api part and doesn't throw a 405 on POST reqest
    rewrite ^/api(.*)$ /$1 break;
    proxy_pass http://backend;
    
    # Not sure if these parameters are required but I'm scared to change anything
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header X-Forwarded-Proto $scheme;
    proxy_set_header X-Forwarded-Host $host;
}

您甚至可以更改重写调用,甚至不更改任何内容,就像这样(但我太懒了,不敢测试它。)

location /api/ {
    rewrite ^/api(.*)$ /api/$1 break;
    proxy_pass http://backend;
}

当然,这也可以通过原始问题中提出的基本 URL 来完成(同样,未经测试,但应该可以工作?)

location / {
    rewrite ^/(.*)$ /$1 break;
    proxy_pass http://backend;
}

-1
投票

我遇到了类似的问题,但仅适用于 Chrome,Firefox 可以正常工作。我注意到 Chrome 在标头请求中添加了 Origin 参数。

因此,在我的 nginx.conf 中,我添加了参数以避免在 location/ 块下出现它

proxy_set_header Origin "";
© www.soinside.com 2019 - 2024. All rights reserved.