4

我正在尝试构建一个 phoenix 应用程序,并处理一个 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

4 回答 4

6

我使用的是 Phoenix 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

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

于 2014-12-21T16:07:31.157 回答
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

于 2014-06-11T18:53:55.363 回答
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
于 2014-06-08T11:27:03.433 回答
0

你需要使用read_body函数。

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

参考

于 2016-09-08T12:44:03.023 回答