gpt4 book ai didi

elixir - 如何为 Phoenix 请求强制执行 JSON 编码?

转载 作者:行者123 更新时间:2023-12-04 15:41:42 28 4
gpt4 key购买 nike

有一些使用 Phoenix 制作的 API,该 API 与 JSON 一起使用。

但是,当您测试它并使用 curl 发送 JSON 时它失败是因为 Phoenix 没有将请求解析为 JSON。您需要明确添加 application/json标题到 curl .我想让它更健壮,并告诉 Phoenix 始终将所有请求解析为 JSON。

有没有办法强制 Phoenix 始终将请求视为 JSON 并将其解析为 JSON?

更新

我尝试使用 plug 设置请求 header ,如@AbM 建议的那样,在路由器中使用以下代码:

def set_format conn, format do Plug.Conn.put_private conn, :phoenix_format, format end

def put_req_header conn, {key, value} do Plug.Conn.put_req_header conn, key, value end

pipeline :api do
plug :put_req_header, {"accept", "application/json"}
plug :put_req_header, {"content-type", "application/json"}
plug :set_format, "json"
plug :accepts, ["json"]
end

已使用 CURL 发出请求
curl -X POST http://localhost:4000/api/upload -d '{"key": "value"}'                    

连接看起来像:
%Plug.Conn{adapter: {Plug.Adapters.Cowboy.Conn, :...}, assigns: %{},
before_send: [#Function<1.93474994/1 in Plug.Logger.call/2>,
#Function<0.119481890/1 in Phoenix.LiveReloader.before_send_inject_reloader/1>],
body_params: %{"{\"key\": \"value\"}" => nil},
cookies: %Plug.Conn.Unfetched{aspect: :cookies}, halted: false,
host: "localhost", method: "POST", owner: #PID<0.483.0>,
params: %{"{\"key\": \"value\"}" => nil},
path_info: ["api", "upload"], peer: {{127, 0, 0, 1}, 58408},
port: 4000,
private: %{App.Router => {[], %{}},
:phoenix_action => :upload,
:phoenix_controller => ApiController, :phoenix_endpoint => App.Endpoint,
:phoenix_format => "json", :phoenix_layout => {LayoutView, :app},
:phoenix_pipelines => [:api],
:phoenix_route => #Function<8.59735990/1 in App.Router.match_route/4>,
:phoenix_router => App.Router, :phoenix_view => ApiView,
:plug_session_fetch => #Function<1.89562996/1 in Plug.Session.fetch_session/1>},
query_params: %{},
query_string: "", remote_ip: {127, 0, 0, 1},
req_cookies: %Plug.Conn.Unfetched{aspect: :cookies},
req_headers: [{"user-agent", "curl/7.37.1"}, {"host", "localhost:4000"},
{"accept", "application/json"}, {"content-length", "16"},
{"content-type", "application/json"}],
request_path: "/api/upload", resp_body: nil, resp_cookies: %{},
resp_headers: [{"cache-control", "max-age=0, private, must-revalidate"},
{"x-request-id", "xxx"}], scheme: :http,
script_name: [],
secret_key_base: "xxx",
state: :unset, status: nil}

如果我添加 -H "Content-Type: application/json" 就可以了CURL 的参数,没有它就不起作用。

最佳答案

如果有人会为此搜索并希望实现此类行为。
lib/%APP_NAME%/endpoint.ex

 plug Plug.Head

# add custom plug
plug :set_format, "json"

定义它:
  defp set_format(conn, format) do
if Regex.match?(~r/^api.*/, conn.host) do
Plug.Conn.put_private conn, :phoenix_format, format
else
conn
end
end

在这个例子中,我们有一个dirty hack,它将为子域 api强制执行JSON格式。

不推荐 这样做,但由于 Phoenix 随时强制执行 HTML,此 hack 修复了荒谬的行为,例如:Elixir.Phoenix.Router.NoRouteError for pipeline :api显示 404.json 而不是 404.html

关于elixir - 如何为 Phoenix 请求强制执行 JSON 编码?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38185875/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com