【问题标题】:nginx redirects POST requests to GET requestnginx 将 POST 请求重定向到 GET 请求
【发布时间】:2014-07-11 06:42:30
【问题描述】:

我有在puma Web 服务器上运行的 Rails 4.1 应用程序。我使用 nginx 作为代理服务器。几天前,一切都很顺利。我更新了我的应用程序,突然一些 POST 请求开始重定向到相同的 url,但作为 GET 请求。我试过回滚到以前的工作版本,没有成功。

我发现了非常有趣的行为。我用curl 测试了我的API。

  • 如果我对 url 进行了POST 请求 http://myapp.com/tasks/easy_task/calculate/ 它重定向到相同的 url 但作为GET 请求。
  • 然后我向http://myapp.com/做了POSTrequest,返回404
  • 然后我向http://myapp.com/tasks做了POSTrequest,返回404
  • 然后我向http://myapp.com/tasks/easy_task做了POSTrequest,返回404
  • 然后我向http://myapp.com/tasks/easy_task/calculate做了POSTrequest,返回200。耶!

当我使用 chrome 的应用程序 Postman 时,也发生了同样的事情。首先它重定向,但经过前面的步骤后它运行良好。

我在我的其他应用程序中使用这个应用程序。我使用RestClient 发出http 请求。当我尝试发出 POST 请求时,它会引发异常 RestClient::MovedPermanently (301 Moved Permanently)

  • 我将nginx 重新安装到1.7.3
  • 重启的服务器(虚拟机)
  • 重新部署我的应用,部署以前的版本
  • 没有成功:(

我在 stackoverflow 上发现了类似的问题,但没有一个给我提供解决此问题的线索。我希望你能帮助我解决这个问题。提前致谢!

类似的问题: - POST request turns into GET request - POST request mysteriously turn into GET request

nginx 配置:

$ cat /etc/nginx/sites-enabled/myapp.com.conf
# The file generated by Chef for mycompany

upstream myapp_mycompany_com {
  server unix:/tmp/myapp.com-puma.sock;
}

server {
  server_name  myapp.com;
  listen       80;

  access_log /var/log/nginx/myapp.com-access.log;
  error_log /var/log/nginx/myapp.com-error.log;

  root /home/projects/mycompany/myapp.com/current/public;

  gzip on;
  gzip_types text/plain text/xml application/xml application/xml+rss
             text/css text/javascript application/javascript application/json;

  error_page 551 =503 @maintenance;
  location @maintenance {
    rewrite ^(.*)$ /system/maintenance.html break;
  }
  set $maintenance 0;
  if (-f $document_root/system/maintenance.html) {
    set $maintenance 1;
  }

  if ($request_uri = /favicon.ico) {
    # Browsers will try to get favicon if it's not returned with 200ok status
    set $maintenance 0;
  }
  if ($maintenance) {
    # There can be several reasons for 503 error. We custom return 551 error
    # to ensure maintenance.html is only shown when it's really maintenance
    return 551;
  }

  rewrite ^/(.*)/$ /$1 permanent; # Truncate trailing slashes
  try_files $uri @rails;

  expires -1;

  location = /favicon.ico {
    try_files $uri =204;
    access_log off;
    log_not_found off;
  }

  location @rails {
    proxy_pass http://myapp_mycompany_com;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header Host $http_host;
    proxy_redirect off;
    proxy_intercept_errors on;
    expires -1;
  }

  error_page 500 502 503 504 /500.html;
  error_page 403 /403.html;
  error_page 404 /404.html;

  client_max_body_size 50M;
  keepalive_timeout 10;
}

彪马

$ bundle exec puma -d -e production -b unix:///tmp/myapp.com-puma.sock --pidfile /home/projects/mycompany/myapp.com/shared/tmp/pids/puma.pid
$

access.log 示例

123.123.123.123 - - [11/Jul/2014:05:44:17 +0000] "POST /tasks/easy_task/calculate/ HTTP/1.1" 301 184 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_9_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/38.0.2073.0 Safari/537.36"
123.123.123.123 - - [11/Jul/2014:05:44:17 +0000] "GET /tasks/easy_task/calculate HTTP/1.1" 404 713 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_9_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/38.0.2073.0 Safari/537.36"

...

123.123.123.123 - - [11/Jul/2014:06:04:17 +0000] "POST / HTTP/1.1" 404 713 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_9_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/38.0.2073.0 Safari/537.36"
123.123.123.123 - - [11/Jul/2014:06:04:26 +0000] "POST /tasks HTTP/1.1" 404 713 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_9_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/38.0.2073.0 Safari/537.36"
123.123.123.123 - - [11/Jul/2014:06:04:36 +0000] "POST /tasks/easy_task HTTP/1.1" 404 713 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_9_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/38.0.2073.0 Safari/537.36"
123.123.123.123 - - [11/Jul/2014:06:04:42 +0000] "POST /tasks/easy_task/calculate HTTP/1.1" 200 104 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_9_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/38.0.2073.0 Safari/537.36"

【问题讨论】:

  • 可能 404 所有这些答案都是由您的 Rails 应用程序生成的。可以显示 nginx error.log 吗?
  • nginx 的 error.log 为空。所有 404 错误都是 rails 应用程序的错误。当 301 时,rails 应用程序甚至没有收到请求。我关闭了 rails 应用程序,无论如何我得到了 301。

标签: ruby-on-rails nginx rest-client puma


【解决方案1】:

我找到了解决方案。当我提出POST 请求时,我使用了以斜杠结尾的url,例如http://myapp.com/tasks/easy_task/calculate/

当我最后使用不带斜线的 url 时,比如http://myapp.com/tasks/easy_task/calculate,一切都完美无缺!

我认为是因为这条规则

rewrite ^/(.*)/$ /$1 permanent; # Truncate trailing slashes

我正在关闭这个问题。明天。

【讨论】:

  • 我的情况正好相反,我发布到/tasks,我的位置定义是/tasks/。感谢您在这里的主题,我找到了解决方案! :)
【解决方案2】:

TL;DR 如果您想完全重定向到新的资源和方法,并且请求的主体不应更改,请使用 308 而不是 301 或 302。

301 是永久重定向,但 302 是临时性的,因此当使用 302 时,搜索引擎不会更改与该网站关联的网址。
301 和 302 表示方法和主体不应更改,但并非所有用户代理都与此一致。阅读 Mozilla 的解释:

超文本传输​​协议 (HTTP) 302 Found 重定向状态响应代码表示请求的资源已临时移动到 Location 标头给出的 URL。浏览器重定向到此页面,但搜索引擎不会更新其指向资源的链接(在“SEO-speak”中,据说“链接汁”不会发送到新 URL)。即使规范要求在执行重定向时不更改方法(和主体),但并非所有用户代理都符合此处 - 您仍然可以在那里找到这种类型的错误软件。因此,建议仅将 302 代码设置为 GET 或 HEAD 方法的响应,并改用 307 临时重定向,因为在这种情况下明确禁止更改方法。如果您希望将使用的方法更改为 GET,请改用 303 See Other。当您想要对不是上传资源而是确认消息的 PUT 方法做出响应时,这很有用,例如:“您已成功上传 XYZ”。

308 和 307 都永久重定向到新资源,但它们保证请求的主体和方法不会被更改。区别在于 308 是永久的,307 是临时的,所以 308 会通知搜索引擎更改 url。看到这个:

307 和 302 唯一的区别是 307 保证重定向请求时方法和正文不会改变。对于 302,一些旧客户端错误地将方法更改为 GET:使用非 GET 方法和 302 的行为在 Web 上是不可预测的,而使用 307 的行为是可预测的。对于 GET 请求,它们的行为是相同的。

【讨论】:

    【解决方案3】:

    就我而言,重定向意味着如果我 POST 到 http://...proxy_pass 将转换为 GET。

    将 URL 更改为 https://... 并按预期作为 POST 传递。

    location /dc1 {
        proxy_pass http://localhost:8000;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_set_header Host www.example.com;
    }
    

    【讨论】:

    • 这肯定会假设将 http 更改为 https 的人会启用 SSL?不过有趣的一点是,可能值得启用 SSL 并查看问题是否消失!
    猜你喜欢
    • 2022-10-26
    • 2019-10-12
    • 1970-01-01
    • 2020-12-17
    • 1970-01-01
    • 2012-12-24
    • 1970-01-01
    • 2019-12-16
    • 1970-01-01
    相关资源
    最近更新 更多