【问题标题】:How do I get request body in phoenix?如何在 phoenix 中获取请求正文?
【发布时间】:2014-06-08 08:05:13
【问题描述】:

我正在尝试构建一个 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"

【问题讨论】:

    标签: erlang elixir phoenix-framework


    【解决方案1】:

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

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

    【讨论】:

      【解决方案2】:

      我刚刚推出了能够轻松访问请求正文的 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

      【讨论】:

      • 不幸的是,我无法测试 Phoenix 0.2.5,因为我的项目使用 amnesia,它在 elixir 0.14.0 上中断...
      【解决方案3】:

      我在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
      

      【讨论】:

        【解决方案4】:

        你需要使用read_body函数。

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

        Reference

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2021-07-22
          • 2021-10-29
          • 2023-03-13
          • 1970-01-01
          • 2019-08-10
          • 2011-12-26
          • 1970-01-01
          • 2019-11-28
          相关资源
          最近更新 更多