Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/elixir/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/sockets/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Elixir 如何正确地将Plug.Static文件的任意路径重新路由到文件?_Elixir_Phoenix Framework - Fatal编程技术网

Elixir 如何正确地将Plug.Static文件的任意路径重新路由到文件?

Elixir 如何正确地将Plug.Static文件的任意路径重新路由到文件?,elixir,phoenix-framework,Elixir,Phoenix Framework,我想跳过Phoenix,因为我正计划为React应用程序构建一个演示,该应用程序的状态使用一些API路由。似乎是一个熟悉底层技术的机会 我提出了以下内容,但感觉非常“硬编码”,我很好奇是否有更优雅的解决方案来实现同样的目标 defmodule DemoApp.Plug.ServeStatic do use Plug.Builder @static_opts [at: "/", from: "priv/static"] plug :default_index plug Plug

我想跳过Phoenix,因为我正计划为React应用程序构建一个演示,该应用程序的状态使用一些API路由。似乎是一个熟悉底层技术的机会

我提出了以下内容,但感觉非常“硬编码”,我很好奇是否有更优雅的解决方案来实现同样的目标

defmodule DemoApp.Plug.ServeStatic do
  use Plug.Builder

  @static_opts [at: "/", from: "priv/static"]

  plug :default_index
  plug Plug.Static, @static_opts
  plug :default_404
  plug Plug.Static, Keyword.put(@static_opts, :only, ["error_404.html"])

  # Rewrite / to "index.html" so Plug.Static finds a match
  def default_index(%{request_path: "/"} = conn, _opts) do
    %{conn | :path_info => ["index.html"]}
  end
  def default_index(conn, _), do: conn

  # Rewrite everything that wasn't found to an existing error file
  def default_404(conn, _opts) do
    %{conn | :path_info => ["error_404.html"]}
  end
end
其思想是让
/
不重定向地提供
index.html
,并在找不到某个内容时提供错误文件的内容,而不是提供最小响应“404 file not found”字符串

有没有一种方法可以实现这一点而不需要插上插头。静电两次,或者这是一种方法?我还可以看到catchall
:default_404
稍后与我的API路由冲突,我不确定如何解决这个问题

任何意见都将不胜感激。谢谢大家!

为此,我将使用和。下面是一些代码,它们可以完成您所做的工作,但更简洁:

defmodule M do
  use Plug.Router

  plug Plug.Static, at: "/", from: "priv/static"
  plug :match
  plug :dispatch

  get "/" do
    send_file(conn, 200, "priv/static/index.html")
  end

  match _ do
    send_file(conn, 404, "priv/static/404.html")
  end
end
由于
:match
:dispatch
是在
Plug.Static
之后插入的,因此
priv/Static
中的任何文件都将在返回到路由器之前得到服务,就像Phoenix一样

使用
priv/static
中的这些文件:

➜ cat priv/static/404.html
404.html
➜ cat priv/static/index.html
index.html
➜ cat priv/static/other.html
other.html
以下是此代码的工作原理:

➜ curl http://localhost:4000
index.html
➜ curl http://localhost:4000/
index.html
➜ curl http://localhost:4000/index.html
index.html
➜ curl http://localhost:4000/other.html
other.html
➜ curl http://localhost:4000/foo
404.html
➜ curl http://localhost:4000/foo/bar
404.html
➜ curl http://localhost:4000/404.html
404.html
➜ curl -s -I http://localhost:4000/foo | grep HTTP
HTTP/1.1 404 Not Found
➜ curl -s -I http://localhost:4000/foo/bar | grep HTTP
HTTP/1.1 404 Not Found
➜ curl -s -I http://localhost:4000/404.html | grep HTTP
HTTP/1.1 200 OK

谢谢,那正是我想要的!我检查了
Plug.Router
文档,当时我正在使用OP-in-one中构建的管道,但完全忘记了我也拥有所有
Plug.Conn
方法。非常感谢。这种方法的一个问题是
send_file
没有
Plug.Static
的所有功能,例如设置缓存头,如
ETag
。有没有办法重写conn的路径并将修改后的请求转发到
Plug.Static
?您还可以将Plug.Router和Plug.Static组合起来启用文件缓存: