Elixir HTTP服务器priv_dir指向_build目录,无法读取源码静态文件
解决Elixir Plug-Cowboy中send_file无法找到priv目录文件的问题
核心问题出在priv目录的位置和Mix的默认行为不匹配:
- Mix项目默认会把根目录下的
priv/文件夹内容复制到编译后的_build/dev/lib/httpserver/priv路径(也就是:code.priv_dir(:httpserver)返回的路径)。 - 你把HTML文件放在
lib/httpserver/priv/index.html,这个目录不在Mix的默认复制范围内,所以编译后_build目录里的priv下没有这个文件,自然找不到。
解决方法
方法1:按Mix规范调整目录结构(推荐)
- 在项目根目录创建
priv/文件夹(如果没有的话)。 - 将
lib/httpserver/priv/index.html移动到priv/index.html。 - 重新启动服务器,
:code.priv_dir(:httpserver)就能正确指向包含index.html的路径了。
方法2:修改Mix配置指定自定义priv目录(不推荐,除非有特殊需求)
如果你一定要保留lib下的priv目录,需要在mix.exs的project函数里指定priv目录的路径:
def project do [ app: :httpserver, version: "0.1.0", elixir: "~> 1.14", start_permanent: Mix.env() == :prod, deps: deps(), priv: "lib/httpserver/priv" # 添加这一行,指定自定义priv目录 ] end
然后执行mix clean && mix compile清理旧编译文件并重新编译,确保Mix将自定义priv目录的内容复制到_build路径中。
验证路径
可以在路由的get "/"方法里临时添加调试代码,确认文件路径是否正确:
get "/" do priv_dir = :code.priv_dir(:httpserver) index_path = Path.join([priv_dir, "index.html"]) IO.inspect(index_path, label: "当前查找的文件路径") # 调试输出 send_file(conn, 200, index_path) end
启动服务器后查看控制台输出,确认路径是否指向存在的文件。
路由代码(无需改动,只要目录正确即可)
defmodule Httpserver.Router do use Plug.Router forward("/static", to: Httpserver.Static) plug :match plug :dispatch get "/" do priv_dir = :code.priv_dir(:httpserver) index_path = Path.join([priv_dir, "index.html"]) send_file(conn, 200, index_path) end get "/:name" do send_resp(conn, 200, "Welcome, #{name} !") end match _ do send_resp(conn, 404, "Not found...") end end
内容的提问来源于stack exchange,提问作者Victor Faure
相关产品推荐
相关产品推荐

