如何配置Elixir Plug.Static仅指定/js/app.js单个文件?
首先,我们一步步排查并解决这个问题:
1. 确认静态文件的实际位置
Plug.Static的from: :main_web对应你main_web应用下的priv/static目录,请先确认priv/static/js/app.js文件确实存在,且文件权限允许应用读取。
如果你的项目用了Webpack、Vite这类前端构建工具,还要检查构建产物的输出路径是否是priv/static/js——有些工具默认会输出到assets/build或其他目录,需要确保构建后的app.js被正确复制到priv/static/js下。
2. 检查是否存在Plug.Static配置冲突
如果你的Endpoint模块里还有其他plug Plug.Static调用(比如Phoenix默认的配置),可能会覆盖当前规则。比如默认配置可能包含only: ~w(css fonts images js),这会优先匹配整个js目录,导致你单独指定的js/app.js不生效。请确保你的自定义Plug.Static配置在默认配置之前执行,或者合并配置规则。
3. 验证请求路径与配置的匹配
Plug.Static的only参数匹配的是相对于at: "/"的请求路径,你写的js/app.js格式是正确的。可以通过添加调试代码确认实际请求路径:
# 在你的Plug.Static配置前添加这个调试plug plug(fn conn, _opts -> IO.inspect(conn.request_path, label: "Incoming Request Path") conn end) plug(Plug.Static, at: "/", from: :main_web, gzip: false, only: ~w(css fonts images webfonts favicon.ico robots.txt sw.js manifest.json js/app.js), headers: %{"Access-Control-Allow-Origin" => "*"} )
运行应用后发起对/js/app.js的请求,查看控制台输出的请求路径是否完全匹配/js/app.js(没有多余的查询参数或路径后缀)。
4. 生产环境的特殊注意事项
如果是在生产环境遇到这个问题,别忘了运行mix phx.digest命令——Phoenix在生产环境会给静态文件生成哈希后缀(比如app-abc123.js),此时原始的app.js会被移到priv/static/static目录下,直接请求/js/app.js会返回404。这种情况下,你应该用Phoenix的静态路径助手生成正确URL:
# 在模板中使用 <%= Routes.static_path(@conn, "/js/app.js") %>
它会自动生成带哈希的路径,确保能正确匹配到静态文件。
5. 尝试切换到only_matching参数
如果以上步骤都没问题,可以尝试把only替换为only_matching参数,它的匹配逻辑更宽松:
plug(Plug.Static, at: "/", from: :main_web, gzip: false, only_matching: ~w(css fonts images webfonts favicon.ico robots.txt sw.js manifest.json js/app.js), headers: %{"Access-Control-Allow-Origin" => "*"} )
only_matching会匹配包含指定路径的请求,而only要求完全匹配,这可能解决一些隐性的路径匹配问题。
内容的提问来源于stack exchange,提问作者Sam Houston

