You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.08 10:52:39