Plug.Parser не читает / анализирует тело JSON - PullRequest
1 голос
/ 29 марта 2019

Я кодирую сервер Elixir (1.8) + Plug_Cowboy (2.0.2) + Jason (1.1.2). Из того, что я получаю из документации, после того, как парсер Plug прошел, у меня должно быть все в body_params. Проблема в том, что доступ к conn.body_params в моем случае возвращает %Plug.Conn.Unfetched{aspect: :body_params}. Проверьте код ниже:

defmodule Test.Router do
  use Plug.Router
  require Logger

  plug :match
  plug Plug.Parsers, parsers: [:json],
                     pass: ["application/json", "text/json"],
                     json_decoder: Jason
  plug :dispatch

  post "/test" do
    Logger.debug inspect(conn.body_params)
    conn
      |> put_resp_content_type("text/plain")
      |> send_resp(204, "Got it")
    end
end

Есть идеи, что происходит?

Я проверяю это с:

curl -H "Content-Type: text/json" -d "{one: 1, two: 2}" 127.0.0.1:8080/test

Я пытался добавить :urlencoded к анализаторам или изменить порядок плагинов, но безрезультатно.

1 Ответ

2 голосов
/ 30 марта 2019

Plug.Parsers.JSON обрабатывает только тип содержимого application/json.По этой причине body_params не заполняется.Ваш тестовый JSON также недопустим - имена свойств объекта не были заключены в кавычки.

curl -H "Content-Type: application/json" -d '{"one": 1, "two": 2}' 127.0.0.1:8080/test

Опция pass: для Plug.Parsers указывает ему игнорировать запросы тех типов, для которых существуетне определен синтаксический анализатор (например, text/json в вашем случае), вместо того, чтобы вызывать UnsupportedMediaTypeError, что обычно и происходит.Добавление этой опции скрывало ошибку.

Может оказаться полезным usePlug.Debugger во время разработки - это даст вам лучшую информацию о том, что происходит в неожиданных ситуациях.

Если по какой-то причине вам нужно иметь возможность анализировать JSON с нестандартным типом text/json (например, из-за запросов от программного обеспечения, которое вы не можете контролировать), вы можете определить новый анализатор для этого типа, которыйпросто оборачивает Plug.Parsers.JSON и переписывает text/json в application/json:

defmodule WrongJson do
  def init(opts), do: Plug.Parsers.JSON.init(opts)

  def parse(conn, "text", "json", params, opts) do
    Plug.Parsers.JSON.parse(conn, "application", "json", params, opts)
  end

  def parse(conn, _type, _subtype, _params, _opts), do: {:next, conn}
end

Затем добавьте его в свой список анализаторов:

plug Plug.Parsers,
  parsers: [:json, WrongJson],
  json_decoder: Jason

Теперь text/json также будет работать.

...