0

当请求到达我的路由器时,我收到此错误OPTIONS "/products"

错误

14:45:33.433 [error] #PID<0.339.0> running Api.Router terminated
Server: 192.168.20.3:4000 (http)
Request: OPTIONS /products
** (exit) an exception was raised:
    ** (Poison.EncodeError) unable to encode value: {:brand, {"can't be blank", [validation: :required]}}
        (poison) lib/poison/encoder.ex:383: Poison.Encoder.Any.encode/2
        (poison) lib/poison/encoder.ex:259: anonymous fn/3 in Poison.Encoder.List.encode/3
        (poison) lib/poison/encoder.ex:260: Poison.Encoder.List."-encode/3-lists^foldr/2-1-"/3
        (poison) lib/poison/encoder.ex:260: Poison.Encoder.List.encode/3
        (poison) lib/poison/encoder.ex:227: anonymous fn/4 in Poison.Encoder.Map.encode/3
        (poison) lib/poison/encoder.ex:228: Poison.Encoder.Map."-encode/3-lists^foldl/2-0-"/3
        (poison) lib/poison/encoder.ex:228: Poison.Encoder.Map.encode/3
        (poison) lib/poison/encoder.ex:227: anonymous fn/4 in Poison.Encoder.Map.encode/3

显示在网络请求期间在前端捕获的错误的图像:

在此处输入图像描述

从上图来看,产品 JSON 对象似乎确实被发送了,因此由于某种原因,它没有正确地将 http post 正文映射到 elixir 变更集。

连接日志:

Interactive Elixir (1.4.1) - press Ctrl+C to exit (type h() ENTER for help)
iex(1)> %{}
%Plug.Conn{adapter: {Plug.Adapters.Cowboy.Conn, :...}, assigns: %{},
 before_send: [], body_params: %{},
 cookies: %Plug.Conn.Unfetched{aspect: :cookies}, halted: false,
 host: "192.168.20.3", method: "OPTIONS", owner: #PID<0.339.0>, params: %{},
 path_info: ["products"], path_params: %{}, peer: {{192, 168, 20, 3}, 63793},
 port: 4000,
 private: %{plug_route: #Function<1.14347947/1 in Api.Router.do_match/4>},
 query_params: %{}, query_string: "", remote_ip: {192, 168, 20, 3},
 req_cookies: %Plug.Conn.Unfetched{aspect: :cookies},
 req_headers: [{"host", "192.168.20.3:4000"}, {"connection", "keep-alive"},
  {"access-control-request-method", "POST"}, {"origin", "http://evil.com/"},
  {"user-agent",
   "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/
537.36"},
  {"access-control-request-headers", "content-type,x-requested-with"},
  {"accept", "*/*"}, {"referer", "http://localhost:8081/debugger-ui"},
  {"accept-encoding", "gzip, deflate, sdch"},
  {"accept-language", "en-GB,en-US;q=0.8,en;q=0.6"}], request_path: "/products",
 resp_body: nil, resp_cookies: %{},
 resp_headers: [{"cache-control", "max-age=0, private, must-revalidate"}],
 scheme: :http, script_name: [], secret_key_base: nil, state: :unset,
 status: nil}
%Api.Product{__meta__: #Ecto.Schema.Metadata<:built, "products">, brand: nil,
 description: nil, id: nil, image: nil, name: nil, numberOfVotes: nil,
 rating: nil}

路由器.ex

defmodule Api.Router do
  use Plug.Router

  if Mix.env == :dev do
    use Plug.Debugger
  end
  plug :match
  plug Plug.Parsers, parsers: [:json],
                   pass:  ["application/json"],
                   json_decoder: Poison
  plug :dispatch

  get "/favicon.ico" do
    # Api.Repo.getCategories(conn)
  end

  get "/categories/" do
    Api.Repo.getCategories(conn)
  end

  options "/categories/" do
    Api.Repo.getCategories(conn)
  end

  post "/products" do
    Api.Repo.insertProduct(conn, conn.body_params)
  end

  options "/products" do
    IO.puts inspect conn.body_params
    Api.Repo.insertProduct(conn, conn.body_params)
  end

  get "/products" do
    Api.Repo.insertProduct(conn, conn.body_params)
  end
end

在 repo.ex

  def insertProduct(conn, product) do
    IO.inspect(conn)
    changeset = Api.Product.changeset(%Api.Product{}, product)
    errors = changeset.errors
    valid = changeset.valid?
    case insert(changeset) do
      {:ok, product} ->
        conn
          |> put_resp_content_type("application/json")
          |> send_resp(200, Poison.encode!(%{
              successs: "success"
          }))
      {:error, changeset} ->

        conn
          |> put_resp_content_type("application/json")
          |> send_resp(500, Poison.encode!(%{
              failure: changeset
          }))
    end
  end

产品.ex

defmodule Api.Product do
  use Ecto.Schema

  @derive {Poison.Encoder, only: [:name, :brand, :description, :image, :rating, :numberOfVotes]}
  schema "products" do
    field :name, :string
    field :brand, :string
    field :description, :string
    field :image, :string
    field :rating, :integer
    field :numberOfVotes, :integer
  end

  def changeset(product, params \\ %{}) do
    product
    |> Ecto.Changeset.cast(params, [:name, :brand, :description, :image, :rating, :numberOfVotes])
    |> Ecto.Changeset.validate_required([:name, :description, :brand])
  end
end

顺便说一句 -由于我用来启用 CORS 的浏览器插件,起源是 evil.com

4

1 回答 1

0

react native 中使用的一些 javascript 全局常量允许网络请求显示在 chrome 开发者控制台中:

GLOBAL.XMLHttpRequest = GLOBAL.originalXMLHttpRequest || GLOBAL.XMLHttpRequest

似乎自己也弄乱了网络请求。一旦我摆脱了该代码,它就会将POSTed 产品插入数据库。

感谢您的评论,这些评论让我受益匪浅。

于 2017-05-23T04:34:18.733 回答