如何在没有 Phoenix 的情况下配置 Plug.Static

How to configure the Plug.Static without Phoenix

我正在尝试弄清楚如何在没有 任何其他框架(Phoenix、Sugar 等)的情况下配置Plug.Static ;只有 Cowboy、Plug 和 Elixir。就是不知道怎么在Router里把东西放在一起。

  plug :match
  plug Plug.Static, at: "/pub", from: :cerber
  plug :dispatch

  get "/" do
    Logger.info "GET /"
    send_resp(conn, 200, "Hello world\n")
  end
  1. Plug.Static 的声明是否在正确的位置?不应该在 plug :dispatch 之后吗?
  2. 我是否需要定义额外的路线
  3. 有了这个声明:
    1. 什么是URL,比如index.html
    2. index.html 在文件系统上的位置

我只是迷路了。

查看 Plug.Router docs 了解 :match:dispatch 的工作原理。 :match 将尝试找到匹配的路由,而 :dispatch 将调用它。这意味着设置中的 Plug.Static 只有在路由器中有匹配的路由时才会被调用,这是没有意义的。你想要 plug Plug.Static 在一切之前。请记住,插件只是按照声明顺序调用的函数。

除此之外,您的 Plug.Static 设置似乎还不错。您当前的配置将在“/pub”提供资源,这意味着“/pub/index.html”将在您的应用中查找 "priv/static/index.html"。更多信息在这里:http://hexdocs.pm/plug/Plug.Static.html

José Valim 所说的一切。这是一个最简单的例子:

defmodule Server do
  use Plug.Builder
  plug Plug.Logger
  plug Plug.Static, at: "/", from: "/path/to/static"
end

这将在“/”端点为“/path/to/static”中的所有静态文件提供服务。

查看文档以获得更多选项和更深入的解释。

这就是我要找的答案。

在应用程序启动方法中使用 Plug.Router with Cowboy:

defmodule HttpServer.Application do
  require Logger
  use Application

  def start(_type, _args) do
    children = [
      {Plug.Adapters.Cowboy2, scheme: :http, plug: HttpServer.Router, options: [port: 4002]}
    ]

    opts = [strategy: :one_for_one, name: HttpServer.Supervisor]

    Supervisor.start_link(children, opts)
  end
end

路由器模块如下所示:

defmodule HttpServer.Router do
  use Plug.Router

  plug(Plug.Logger)
  plug(:redirect_index)
  plug(:match)
  plug(:dispatch)

  forward("/static", to: HttpServer.StaticResources)

  get "/sse" do
    # some other stuff...
    conn
  end

  match _ do
    send_resp(conn, 404, "not found")
  end

  def redirect_index(%Plug.Conn{path_info: path} = conn, _opts) do
    case path do
      [] ->
        %{conn | path_info: ["static", "index.html"]}

      ["favicon.ico"] ->
        %{conn | path_info: ["static", "favicon.ico"]}

      _ ->
        conn
    end
  end
end

这里对“/static”的请求被转发到HttpServer.StaticResources模块,但是首先,用plug(:redirect_index).所有静态文件(*.html、*.ico、*.css、*.js 等)都放在默认位置(project_dir/priv/static)。

最后,静态资源模块:

defmodule HttpServer.StaticResources do
  use Plug.Builder

  plug(
    Plug.Static,
    at: "/",
    from: :http_server
  )

  plug(:not_found)

  def not_found(conn, _) do
    send_resp(conn, 404, "static resource not found")
  end
end