从/在Phoenix Framework中提供静态html及其他 Conf I Conf II

问题描述

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

  • /应该投放index.html文件
  • /some/file.html应该提供file.html目录中的some文件,前提是该路径存在,如果路径不存在则为404;
  • 诸如/some/之类的网址应发回403或404以阻止目录列表
  • /api下的所有内容均由专用控制器进行管理。

该项目是使用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错误页面我只是不知道告诉凤凰网在什么地方以及如何发送回403或404(/除外)。
  • 在未退出文件调用URL不会发送回404,而是会发回Phoenix错误页面。我试图在static中创建一个router.ex管道,但似乎流程没有到达那里。文档指出:如果找不到静态资产,Plug.Static只会将连接转发到管道的其余部分。,但是我看不到将404答复放在何处。

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

Conf I

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

Conf II

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

# router.ex
...
  pipeline :static do
    plug :put_secure_browser_headers
    plug Plug.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 文件的唯一方法如下:

  • 我不得不像您一样从 endpoint.ex 文件中的 only: 中删除 Static.Plug 选项。
  • 按照这个答案: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

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

我希望这也能帮到你。

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...