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

使用Prawn生成的PDF在浏览器查看器下载时提示服务器错误

解决方案:Prawn生成PDF inline显示后下载报错问题

以下是几个可行的排查和解决方向:

1. 检查文件权限与路径

确保生成的PDF文件权限正确,且用绝对路径构建避免Rails路径解析问题:

file_path = Rails.root.join('public', 'assets', 'reports', 'test_report.pdf')
pdf.render_file file_path
# 确保服务器进程可读取文件
File.chmod(0644, file_path)

send_file(file_path, filename: 'test_report.pdf', type: 'application/pdf', disposition: 'inline')

2. 改用send_data直接传递PDF内容(跳过文件写入)

绕开本地文件读写可能带来的权限/缓存问题,直接发送Prawn生成的PDF内容:

pdf = <调用生成PDF的方法>
send_data(
  pdf.render,
  filename: 'test_report.pdf',
  type: 'application/pdf',
  disposition: 'inline',
  # 补充Content-Length头帮助浏览器处理下载
  headers: { 'Content-Length' => pdf.render.size.to_s }
)

3. 调整响应头避免编码或缓存冲突

针对浏览器对inline模式下载的处理特性,补充必要的响应头:

send_file(
  file_path,
  filename: 'test_report.pdf',
  type: 'application/pdf',
  disposition: 'inline',
  headers: {
    'Cache-Control' => 'no-cache, no-store, must-revalidate',
    'Pragma' => 'no-cache',
    'Expires' => '0',
    # 显式指定文件名编码,避免特殊字符干扰
    'Content-Disposition' => "inline; filename*=UTF-8''#{URI.encode_www_form_component('test_report.pdf')}"
  }
)

4. 切换PDF存储目录

public/assets属于静态资源目录,可能被asset pipeline或CDN缓存干扰,建议改用tmp目录存储临时PDF:

file_path = Rails.root.join('tmp', 'reports', 'test_report.pdf')
# 确保目录存在
FileUtils.mkdir_p(File.dirname(file_path))
pdf.render_file file_path

send_file(file_path, filename: 'test_report.pdf', type: 'application/pdf', disposition: 'inline')
# 请求结束后清理临时文件
at_exit { File.delete(file_path) if File.exist?(file_path) }

内容的提问来源于stack exchange,提问作者Frank Antony

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.01 03:41:28