我如何获得凤凰的请求体?

时间:2014-06-08 08:05:14

标签: erlang elixir phoenix-framework

我正在尝试构建一个凤凰应用程序,并处理POST请求。我想获得请求正文,而我似乎无法找到有关如何执行此操作的任何文档。

进行一些逆向工程我得到了以下代码:

defmodule MyApp.Controllers.Pages do
  use Phoenix.Controller

  def post(conn) do
    {_, {_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, body, _, _, _, _, _, _}} = conn.adapter
    text conn, "#{inspect body}"
  end
end

有路由:

defmodule MyApp.Router do
  use Phoenix.Router

  post "/test", MyApp.Controllers.Pages, :post
end

必须有更好的方法,不是吗?

预期行为:

curl -XPOST localhost:4000/test -d 'this is a test'
$ "this is a test"

4 个答案:

答案 0 :(得分:6)

我正在使用凤凰版0.6.1,我无法使上述方法起作用。我发现以下工作:

defmodule MyApp.MyController do
  use Phoenix.Controller

  plug :action 

  def login(conn, _params) do
    {:ok, data, _conn_details} = Plug.Conn.read_body(conn)

    # ...
  end
end

请求正文以数据形式返回。不确定这是否是获取请求正文的“官方”方式,但我想我会分享它。

答案 1 :(得分:1)

我只是推出了Phoenix 0.2.5,能够轻松访问请求体。 Plug 4.4刚刚发布,以支持collect_body(conn, "")。此函数是在Phoenix控制器的上下文中导入的,因此您应该能够使用collect_body(conn, "")简单地将整个主体作为字符串。如果你无法让它发挥作用,请给它一个机会并打开一个Github问题。

https://github.com/elixir-lang/plug/blob/master/lib/plug/conn.ex#L355-L394

答案 2 :(得分:0)

我在elixir-lang的测试中找到了这个:

defmodule MyApp.Controllers.Pages do
  use Phoenix.Controller

  def post(conn) do
    body = read_req_body(conn)
    text conn, "#{inspect body}"
  end

  defp read_req_body({:ok, buffer, state}, acc, adapter) do
    read_req_body(adapter.stream_req_body(state, 100_000), acc <> buffer, adapter)
  end

  defp read_req_body({:done, state}, acc, _adapter) do
    {acc, state}
  end

  defp read_req_body(%{adapter: {adapter, state}}) do
    {body, _} = read_req_body({:ok, "", state}, "", adapter)
    body
  end
end

答案 3 :(得分:0)

您需要使用read_body功能。

  

此函数读取请求体的块,直到给定:length。   如果要读取更多数据,则{:more,partial_body,conn}为   回。否则返回{:ok,body,conn}。如果出现错误   读取套接字,按:返回{:error,reason}   :gen_tcp.recv / 2

Reference