我在puma
网络服务器上运行Rails 4.1应用程序。我使用nginx作为代理服务器。几天前一切都很顺利。我更新了我的应用程序,突然有些POST
个请求开始重定向到同一个网址但是GET
请求。我已经尝试回滚到以前的工作版本,没有成功。
我发现了非常有趣的行为。我用curl
测试了我的API。
POST
请求
http://myapp.com/tasks/easy_task/calculate/
它重定向到相同的网址
但是GET
请求。POST
请求http://myapp.com/
,返回404 POST
请求http://myapp.com/tasks
,返回404 POST
请求http://myapp.com/tasks/easy_task
,返回404 POST
请求http://myapp.com/tasks/easy_task/calculate
,返回200. YAY!当我使用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 config:
$ 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"
答案 0 :(得分:3)
我找到了解决方案。当我POST
请求时,我使用了以斜杠结尾的网址,例如http://myapp.com/tasks/easy_task/calculate/
当我最后使用没有斜线的网址时,就像http://myapp.com/tasks/easy_task/calculate
一切都完美无缺!
我认为这是因为这条规则
rewrite ^/(.*)/$ /$1 permanent; # Truncate trailing slashes
我正在结束这个问题。明天。
答案 1 :(得分:0)
301 是永久性重定向,而 302 是临时性的,因此在使用 302 时搜索引擎不会更改与该网站关联的网址。
301 和 302 指示方法和主体不应更改,但并非所有用户代理都与此一致。阅读 Mozilla 的解释:
超文本传输协议 (HTTP) 302 Found 重定向状态响应代码表示请求的资源已临时移动到 Location 标头给出的 URL。浏览器重定向到此页面,但搜索引擎不会更新其指向资源的链接(在“SEO-speak”中,据说“link-juice”不会发送到新 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 请求,它们的行为是相同的。
TL;博士 如果您想完全重定向到新的资源和方法以及不应更改请求的主体,请使用 308 而不是 301 或 302。
答案 2 :(得分:0)
就我而言,重定向意味着如果我 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;
}