使用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
相关产品推荐
相关产品推荐

