在Heroku环境中,POST请求被视为GET请求。

8
我有一个奇怪的案例。我有一个RoR应用程序,提供REST API,我从Java应用程序连接到它。
我在本地开发RoR,并在Heroku环境中部署它。
无论我使用什么方法(从Java APP、Mozilla REST客户端等)发送应该由API控制器中的create操作处理的POST HTTP请求。在本地主机上,一切正常。在Heroku生产环境中,POST请求被视为普通的GET请求。
这是我的资源路由:
        api_v1_items GET    /api/v1/items(.:format)                            api/v1/items#index {:format=>:json}
                     POST   /api/v1/items(.:format)                            api/v1/items#create {:format=>:json}
         api_v1_item GET    /api/v1/items/:id(.:format)                        api/v1/items#show {:format=>:json}
                     PATCH  /api/v1/items/:id(.:format)                        api/v1/items#update {:format=>:json}
                     PUT    /api/v1/items/:id(.:format)                        api/v1/items#update {:format=>:json}
                     DELETE /api/v1/items/:id(.:format)                        api/v1/items#destroy {:format=>:json}

我正在尝试向/api/v1/items发出POST请求,传递所有必要的参数。

在本地主机上,响应是正确的:

Started POST "/api/v1/items?token=l4XOHrhDApPqTp1u4TxBjQ" for 127.0.0.1 at 2014-05-15 22:11:49 +0200
Processing by Api::V1::ItemsController#create as JSON
Parameters: {"height"=>10.0, "item_name"=>"Super item", "width"=>20.0, etc...

然而,在Heroku上发送相同的请求会被视为GET请求:
2014-05-15T20:27:58.137541+00:00 app[web.1]: Started GET "/api/v1/items?token=iEdDkDLiDUlWi0mDbr6XYw" for 89.74.57.51 at 2014-05-15 20:27:58 +0000
2014-05-15T20:27:58.223620+00:00 app[web.1]: Processing by Api::V1::ItemsController#index as JSON

任何想法?当然,两个仓库都是同步的。已经检查过几次了。
这真的很奇怪...也许是某种Heroku缓存魔法?

你能用curl重现这个问题并且发布你的示例吗? - catsby
感谢您激励我使用curl,以下是解决方案。 - Maciek Simm
1
我遇到了类似的问题:我在POST请求时使用了myapp.heroku.com而不是myapp.herokuapp.com -- 后者解决了问题。但是从myapp.heroku.com进行GET请求是可以的。 - Benny
4个回答

7

HTTP/1.1 301 Moved Permanently

301重定向并非Heroku的魔法。您的DNS(或可能是应用程序)可能会将所有顶级请求(mydomain.com)转发到www子域。

使用子域名更为推荐:


1
现在是凌晨2点;你刚刚拯救了我的夜晚! - Benny
1
三年后...仍在拯救生命 <3 - Juan Fuentes

5

我也是。感谢你记录这个! - francisoreilly
谢谢您发布这个问题,这可能解决了我们的问题!快速澄清一下:http://my-app.heroku.com 在浏览器中可以正常解析我们的应用程序;为什么需要使用 http://my-app.herokuapp.com?再次感谢。 - Crashalot

2

好的,我试了CURL,但出现了一个愚蠢的错误。

我在http://mydomain.com发帖子,该站点使用GET路由。 当我在http://www.mydomain.com上发布时,它有效。

Heroku魔法。

以下是curl和结果供您参考。也许有人能解释为什么会这样工作...

在mydomain.com上发布

curl -v -H "Accept: application/json" -H "Cont"width":20.0,"item_desc":"The super item","std_pack":40,"sku":"A1004","depth":20.0}}'  http://mydomain.com/api/v1/items?token=dSWeyKjjtZu0ZSs6b2J-yw
* Adding handle: conn: 0x7fe70b803000
* Adding handle: send: 0
* Adding handle: recv: 0
* Curl_addHandleToPipeline: length: 1
* - Conn 0 (0x7fe70b803000) send_pipe: 1, recv_pipe: 0
* About to connect() to mydomain.com port 80 (#0)
*   Trying 78.46.51.229...
* Connected to mydomain.com (78.46.51.229) port 80 (#0)
> POST /api/v1/items?token=dSWeyKjjtZu0ZSs6b2J-yw HTTP/1.1
> User-Agent: curl/7.30.0
> Host: mydomain.com
> Accept: application/json
> Content-type: application/json
> Content-Length: 174
> 
* upload completely sent off: 174 out of 174 bytes
< HTTP/1.1 301 Moved Permanently
< Date: Thu, 15 May 2014 21:20:58 GMT
* Server Apache is not blacklisted
< Server: Apache
< Location: http://www.mydomain.com/api/v1/items?token=dSWeyKjjtZu0ZSs6b2J-yw
< Content-Length: 273
< Content-Type: text/html; charset=iso-8859-1
< 
<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
<html><head>
<title>301 Moved Permanently</title>
</head><body>
<h1>Moved Permanently</h1>
<p>The document has moved <a href="http://www.mydomain.com/api/v1/items?token=dSWeyKjjtZu0ZSs6b2J-yw">here</a>.</p>
</body></html>
* Connection #0 to host mydomain.com left intact

在www.mydomain.com上进行POST请求

Maciejs-MacBook-Pro:merchbag maciejsimm$ curl -v -H "Accept: application/json" -H "Content-type: application/json" -X POST -d '{"item":{"height":10.0,"item_name":"Super duper item","width":20.0,"item_desc":"The super","std_pack":40,"sku":"A1005","depth":20.0}}'  http://www.mydomain.com/api/v1/items?token=dSWeyKjjtZu0ZSs6b2J-yw
* Adding handle: conn: 0x7fc191003000
* Adding handle: send: 0
* Adding handle: recv: 0
* Curl_addHandleToPipeline: length: 1
* - Conn 0 (0x7fc191003000) send_pipe: 1, recv_pipe: 0
* About to connect() to www.mydomain.com port 80 (#0)
*   Trying 50.17.185.176...
* Connected to www.mydomain.com (50.17.185.176) port 80 (#0)
> POST /api/v1/items?token=dSWeyKjjtZu0ZSs6b2J-yw HTTP/1.1
> User-Agent: curl/7.30.0
> Host: www.mydomain.com
> Accept: application/json
> Content-type: application/json
> Content-Length: 133
> 
* upload completely sent off: 133 out of 133 bytes
< HTTP/1.1 201 Created 
< Cache-Control: max-age=0, private, must-revalidate
< Content-Type: application/json; charset=utf-8
< Date: Thu, 15 May 2014 21:24:17 GMT
< Etag: "41231ae0f50a604cd7316a014d19b3f2"
* Server WEBrick/1.3.1 (Ruby/2.0.0/2014-05-08) is not blacklisted
< Server: WEBrick/1.3.1 (Ruby/2.0.0/2014-05-08)
< Set-Cookie: request_method=POST; path=/
< X-Content-Type-Options: nosniff
< X-Frame-Options: SAMEORIGIN
< X-Request-Id: ba05dd74-bf52-47d5-b8a9-d0516aff5804
< X-Runtime: 0.020289
< X-Ua-Compatible: chrome=1
< X-Xss-Protection: 1; mode=block
< Content-Length: 234
< Connection: keep-alive
< 
* Connection #0 to host www.mydomain.com left intact
{"id":15,"partner_id":1,"sku":"A1005","item_name":"Super duper item","item_desc":"The super","std_pack":40,"height":10,"width":20,"depth":20,"image":null,"created_at":"2014-05-15T21:24:17.753Z","updated_at":"2014-05-15T21:24:17.761Z"} 

-1
当我使用HTTP而不是HTTPS向Heroku发送POST请求时,我遇到了同样的问题。每次Heroku将我的POST请求路由为GET请求。一旦我更新了URL以使用HTTPS,我的POST请求就被Heroku路由为POST而不是GET,解决了这个问题。前面帖子中提到的重定向问题很可能是我遇到的问题的根本原因。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接