如何在服务端限制文件上传大小?Phoenix框架场景下的疑问
如何在Phoenix服务端限制文件上传大小
由于控制器的create函数会在文件完全上传后才触发,所以需要在请求处理的更早阶段设置限制,以下是几种可行方案:
1. 通过Plug.Parsers全局限制上传总大小
Phoenix依赖Plug.Parsers处理请求体,包括multipart类型的文件上传。你可以在项目的lib/your_app_web/endpoint.ex中修改该Plug的配置,直接限制上传内容的总大小:
plug Plug.Parsers, parsers: [:urlencoded, :multipart, :json], pass: ["*/*"], json_decoder: Phoenix.json_library(), # 限制multipart上传总大小为10MB(单位:字节) length: 10_485_760, length_field: "content-length", # 可选:设置超出限制后的响应状态码 override_headers: %{"content-length" => "0"}
当上传文件超过该限制时,Plug会直接返回413状态码,不会完成文件上传,也不会进入控制器逻辑。
2. 在Ecto Changeset中验证单个文件大小
如果需要针对特定文件(比如你的CSV文件)做精细的大小验证,可以在对应的Changeset中添加自定义验证逻辑,虽然文件已上传,但可以在保存前拒绝并清理临时文件:
在你的Batch schema对应的Changeset函数中添加验证:
def changeset(batch, attrs) do batch |> cast(attrs, [:其他字段]) |> validate_csv_file_size(attrs["csv"]) end defp validate_csv_file_size(changeset, nil), do: changeset defp validate_csv_file_size(changeset, upload) do max_size = 10_485_760 # 10MB if upload.size > max_size do add_error(changeset, :csv, "文件大小不能超过#{div(max_size, 1024*1024)}MB") else changeset end end
当文件大小超出限制时,Changeset会携带错误信息返回,你可以在模板中渲染该错误提示用户。
3. 若使用Phoenix LiveView:通过上传组件实时限制
如果项目基于Phoenix LiveView开发,可以直接利用LiveView的上传组件在服务端配置大小限制,上传过程中就会终止过大的文件:
在LiveView模块的mount函数中配置上传规则:
def mount(_params, _session, socket) do {:ok, socket |> allow_upload(:csv, accept: [".csv"], max_file_size: 10_485_760, # 10MB max_entries: 1 )} end
内容的提问来源于stack exchange,提问作者Chen Yu
相关产品推荐
相关产品推荐

