如何在Shrine中使用Upload Endpoint插件及解决GET请求路由错误
解决Shrine中GET请求缓存图片的RoutingError问题
看起来你遇到的核心问题是缓存文件的存储路径和路由配置不匹配,导致POST上传成功后,GET请求无法找到对应的文件路径。我来一步步帮你排查修复:
1. 为什么会出现这个错误?
先拆解几个关键配置的矛盾点:
- 你把Shrine的缓存存储放在了
app/assets/images/uploads/cache,但Rails默认不会将app/assets下的动态上传文件作为静态资源提供服务——app/assets是给预编译的静态资源用的,动态生成的上传文件放这里会被忽略。 - 你的
upload_endpoint挂载到了"/app/assets/images/uploads",但Shrine的upload_endpoint插件(配置了url: true)返回的uploadURL是"/uploads/cache/...",这就导致GET请求的路径和路由挂载的路径完全不匹配,自然找不到对应的路由。
2. 修复步骤
第一步:调整Shrine的存储目录到public
把上传文件移到Rails默认的静态文件服务目录public下,这样Rails可以直接返回文件,同时也能和upload_endpoint的路由匹配:
修改shrine.rb中的存储配置:
Shrine.storages = { cache: Shrine::Storage::FileSystem.new("public", prefix: "uploads/cache"), # 缓存文件现在存在 public/uploads/cache store: Shrine::Storage::FileSystem.new("public", prefix: "uploads"), # 永久文件存在 public/uploads }
第二步:修正upload_endpoint的路由挂载
让路由挂载路径和Shrine返回的uploadURL一致,把upload_endpoint挂载到"/uploads":
修改routes.rb:
# 替换原来的 upload_endpoint 挂载行 mount ImageUploader.upload_endpoint(:cache) => "/uploads"
第三步:验证配置是否生效
现在上传文件后,Shrine返回的uploadURL会是"/uploads/cache/47eee6dc368f20db1e26fa5176552136.jpg":
- 当你发起GET请求时,
upload_endpoint的路由会匹配这个路径并返回文件; - 同时因为文件实际存在
public/uploads/cache下,即使没有upload_endpoint,Rails的静态文件服务也能直接返回它。
3. 额外注意事项
- 永远不要把动态上传的文件放在
app/assets目录下,这个目录是给需要预编译的静态资源(比如你写的CSS、JS、设计图)用的,动态上传的文件会导致预编译混乱,也无法被Rails静态服务正确识别。 - 如果需要对缓存文件做权限控制,可以在
upload_endpoint中添加自定义逻辑,比如验证当前用户是否有权访问该文件:# 在 ImageUploader 中配置 upload_endpoint plugin :upload_endpoint, url: true do |uploader, request| # 这里添加权限校验逻辑,比如: unless request.session[:user_id].present? [403, {}, ["Forbidden"]] end end
内容的提问来源于stack exchange,提问作者Mick mic
相关产品推荐
相关产品推荐

