【问题标题】:Serving static html (and others) from / in Phoenix Framework从/在 Phoenix 框架中提供静态 html(和其他)
【发布时间】:2021-05-02 03:44:19
【问题描述】:

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

  • / 应该为 index.html 文件提供服务;
  • /some/file.html 应该提供来自some 目录的file.html 文件,前提是路径存在,如果路径不存在,则为 404;
  • /some/ 等 URL 应返回 403 或 404 以阻止目录列表
  • /api 下的所有内容均由专用控制器管理。

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

我必须从 endpoint.ex 中的 plug Plug.Static 的参数列表中删除 only: ~w(css fonts images js favicon.ico robots.txt) 才能在根 URL 处提供文件。除错误外,一切正常:

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

这是我尝试的两种配置:

配置我

# 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)
...

会议二

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

# 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

【问题讨论】:

    标签: phoenix-framework plug


    【解决方案1】:

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

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

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

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

    get "/", PageController, :index
    

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

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

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

    我希望这对你也有帮助。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-03-04
      • 2016-10-11
      • 1970-01-01
      • 2023-04-11
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多