Rails中点击下载时动态生成attachment_url以避免链接过期
解决动态附件链接过期问题的方案
1. 新增控制器生成临时链接的Action
在对应业务控制器(比如StaffProfilesController)中添加一个action,用于在用户触发下载时实时生成有效链接:
def download_attachment @staff = Staff.find(params[:id]) # 替换为你实际要下载的附件属性 temp_url = @staff.attachment_url(@staff.target_attachment) redirect_to temp_url, allow_other_host: true end
这个action会在用户点击下载时才调用attachment_url生成30秒有效期的链接,然后重定向到该地址完成下载。
2. 配置对应路由
在config/routes.rb中添加路由映射,让前端请求能指向上面的action:
resources :staff_profiles do get 'download_attachment', on: :member end
配置后会生成类似 /staff_profiles/:id/download_attachment 的路由地址。
3. 更新视图中的下载链接
把原来直接生成attachment_url的静态链接,替换为指向控制器action的动态链接:
<%= link_to '下载附件', download_attachment_staff_profile_path(@staff), class: 'btn-download' %>
用户点击该链接时,会先请求控制器的download_attachmentaction,获取最新的有效临时链接后再跳转下载,彻底避免链接提前过期的问题。
可选:图片链接的过期优化
如果担心页面长时间停留后图片链接过期,可以通过JS动态获取有效链接:
控制器新增图片链接接口
def image_url @staff = Staff.find(params[:id]) render plain: @staff.attachment_url(@staff.image) end
路由补充配置
resources :staff_profiles do get 'download_attachment', on: :member get 'image_url', on: :member end
视图中用JS动态加载图片
<img id="staff-avatar" alt="No image" width="100px" height="100px" data-staff-id="<%= @staff.id %>"> <script> // 页面加载时获取图片链接 const img = document.getElementById('staff-avatar'); function loadImageUrl() { fetch(`/staff_profiles/${img.dataset.staffId}/image_url`) .then(res => res.text()) .then(url => img.src = url); } loadImageUrl(); // 图片加载失败时重新获取链接(应对过期情况) img.addEventListener('error', loadImageUrl); </script>
这样图片在加载失败(链接过期)时会自动重新请求最新的有效链接,保证图片正常显示。
内容的提问来源于stack exchange,提问作者Mohammad Yusuf
相关产品推荐
相关产品推荐

