phoenix-framework - 从 Phoenix 框架/在 Phoenix 框架中提供静态 html(和其他)

标签 phoenix-framework plug

我正在开发一个使用 Phoenix 框架实现的 API 服务器。 JSON API 由 /api/<version> 提供网址。服务器还需要提供静态.html (以及其他, .css.js 等)来自 / 的文件:它实际上是用另一种语言开发的一个小 SPA,并编译为 HTML5、JS 和 CSS。行为应该是:

  • /应该服务于 index.html文件;
  • /some/file.html应该服务于 file.html文件来自some路径存在则返回 404,如果不存在则返回 404;
  • 类似 /some/ 的网址应发回 403 或 404 以防止目录列出
  • /api下的所有内容由专用 Controller 管理。

该项目是用 mix phx.new --no-ecto --no-html --no-gettext --no-webpack static 生成的摆脱.css , .js文件和模板。我还创建了一个priv/static静态资源目录。

我必须删除only: ~w(css fonts images js favicon.ico robots.txt)来自plug Plug.Static的参数列表在endpoint.ex让根 URL 处的文件得到服务。除了错误之外,一切正常:

  • 关于 / 的请求显示 Phoenix 错误页面,日志为 [debug] ** (Phoenix.Router.NoRouteError) no route found for GET / (StaticWeb.Router) 。我添加了 {:plug_static_index_html, "~> 1.0"}所以我摆脱了这个问题,但调用 /subdir发回 Phoenix 错误页面。 我只是不知道在哪里以及如何告诉 Phoenix 发回 403 或 404(/ 除外)。
  • 在不存在的文件上调用 URL 不会发回 404,而是发回 Phoenix 错误页面。我试图创建一个 static管道 router.ex但似乎流量没有到达那里。文档指出:如果找不到静态资源,Plug.Static只是将连接转发到管道的其余部分。但是我不知道在哪里放置 404 回复

这是我尝试过的两种配置:

session 一

# endpoint.ex
...
  # Serve at "/" the static files from "priv/static" directory.
  plug Plug.Static.IndexHtml, at: "/"
  plug Plug.Static,
    at: "/",
    from: :static,
    gzip: false
    # only: ~w(css fonts images js favicon.ico robots.txt)
...

session 二

我从 endpoint.ex 中删除了所有与静态内容相关的内容并添加了static管道 router.ex

# router.ex
...
  pipeline :static do
    plug :put_secure_browser_headers
    plug Plug.Static,
      at: "/",
      from: :static,
      gzip: false # ,
      # only: ~w(css fonts images js favicon.ico robots.txt)
    plug :not_found
  end
  
  scope "/", staticWeb do
    pipe_through :static
  end

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

任何提示都会有帮助。

2020 年 8 月 13 日更新

在范围 "/" 上添加了一条包罗万象的规则在 router.ex 末尾至少我会因为任何错误请求而收到 404 错误。我只是想知道这一切有多干净......

# router.ex
...
  scope "/", AlaaarmWeb do
    match :*, "/*path", DefController, :error_404
  end

最佳答案

我遇到了同样的问题,我试图提供使用 create-react-app 创建的 SPA,并将所有生成的文件放在 priv/static 文件夹中。

我发现从根路径提供静态index.html 文件的唯一方法如下:

  • 我必须像您一样从端点.ex 文件中的 Static.Plug 中删除 only: 选项。
  • 按照这个答案:https://stackoverflow.com/a/37568770/8620481 ,我采取了不同的策略。我没有尝试直接提供静态文件,而是将其内容作为字符串读取,然后从 Controller 提供它。

特别是,在 router.ex 文件中的 "/" 范围下,我定义了以下路由:

get "/", PageController, :index

在PageController中,我实现了index方法,如下:

def index(conn, _params) do
  file = File.read!("priv/static/index.html")
  html(conn, file)
end

我不知道静态插头背后的机制到底是什么,但我发现这个解决方法对于我的用例来说是可以接受的。

希望这也能帮到你。

关于phoenix-framework - 从 Phoenix 框架/在 Phoenix 框架中提供静态 html(和其他),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63378017/

相关文章:

testing - 如何编写测试插头错误处理

postgresql - 关于约束错误的令人困惑的错误消息

testing - 修复我的 Phoenix.Channel 的 terminate/2 方法测试中的 “owner #PID<…> exited with: shutdown”

Elixir phoenix 注销链接无效

azure - 如何在 IoT 即插即用 DTDL 定义中表示 C2D 消息

使用 Bamboo 而不是凤凰的电子邮件模板

elixir - HMAC、Elixir、Plug.Conn(尝试多次调用 read_body)

elixir - Phoenix _ecto : error when loading assoc

postgresql - mix deps.get 失败(依赖问题)