Mil*_*ous 1 elixir phoenix-framework
我正在考虑跳过凤凰城,因为我只打算为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
Run Code Online (Sandbox Code Playgroud)
这个想法是让/服务index.html没有重定向,并在找不到某些东西时提供错误文件的内容,而不是最小的响应"404 file not found"字符串.
有没有办法实现这一点,而无需插入Plug.Static两次,或者这是要走的路?我:default_404后面也可以看到catchall 与我的API路径发生冲突,我不知道如何解决这个问题.
任何输入都将非常感激.谢谢!
我会用Plug.Router和Plug.Conn.send_file/5这个.这里有一些代码可以做你做的但更清洁:
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
Run Code Online (Sandbox Code Playgroud)
当插入: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
Run Code Online (Sandbox Code Playgroud)
以下是此代码的工作原理:
? 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
Run Code Online (Sandbox Code Playgroud)