Elixir 如何正确地将Plug.Static文件的任意路径重新路由到文件?
我想跳过Phoenix,因为我正计划为React应用程序构建一个演示,该应用程序的状态使用一些API路由。似乎是一个熟悉底层技术的机会 我提出了以下内容,但感觉非常“硬编码”,我很好奇是否有更优雅的解决方案来实现同样的目标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
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组合起来启用文件缓存: