不允许POST请求 - 405 Not Allowed - nginx,即使包含头文件也是如此

时间:2014-06-25 17:52:53

标签: node.js express nginx cross-domain nodemailer

我在尝试在我的应用程序中执行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

在这行代码中:

file.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:

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

我现在在做什么:

我正在尝试从服务器的其他域发布信息:

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

POST LISTENER:&#34; http://xxx.xxx.x.xx:9000/email,服务器localhost(x-&gt;我的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();
        });

有人知道如何解决它吗?

谢谢。

7 个答案:

答案 0 :(得分:43)

这个配置到你的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;

    # ...
}

答案 1 :(得分:2)

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

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;

  }
}

答案 2 :(得分:1)

我注意到这并没有使用静态优先然后反向代理设置。这是什么样的:

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

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

答案 3 :(得分:1)

在我的情况下,这是JSON的POST提交要处理并获得返回值。我在使用和不使用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;
}

有效。

答案 4 :(得分:0)

我已经尝试了将重定向405到200的解决方案,并且在生产环境中(在我的情况下,它是使用Nginx Docker容器的Google负载平衡),这个hack会导致一些502错误(Google Load Balancing错误代码: 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

答案 5 :(得分:0)

我遇到了类似的问题,但只有Chrome浏览器可以使用Firefox。我注意到Chrome在标头请求中添加了Origin参数。

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

proxy_set_header Origin "";

答案 6 :(得分:0)

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

我犯了一个新手错误,忘记在生产服务器上创建 env.production.local,因此在构建 VueJs 应用程序时,url 从未被选中。因此,所有请求都被路由到例如 example.com/signin 而不是 api.example.com/signin,从而导致错误。

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