Wicked PDF生成PDF时图片无法显示问题求助(Ruby on Rails环境)
问题根因与解决方案
核心问题原因
- Wicked PDF 依赖的
wkhtmltopdf工具在后台渲染时不携带当前用户的会话cookie,你浏览器能访问图片是因为处于登录态,而wkhtmltopdf请求需要认证的Active Storage资源时会被权限拦截返回404 - 默认
url_for生成的是相对路径,wkhtmltopdf无法解析非绝对路径的资源地址 - 部分旧版本
wkhtmltopdf不支持webp等新式图片格式
解决方案
方案1:直接嵌入Base64图片(最稳妥,全环境兼容)
直接把图片转成Base64编码嵌入HTML,完全不需要外部资源请求,不会出现路径、权限问题。修改视图中的图片标签代码:
<%# 品牌logo部分修改 %> <% if @certificate.certificate_template.brand_logo.attached? %> <% logo_blob = @certificate.certificate_template.brand_logo.blob %> <%= wicked_pdf_image_tag "data:#{logo_blob.content_type};base64,#{Base64.strict_encode64(logo_blob.download)}", width: '400px' %> <% elsif current_tenant && current_tenant.has_custom_domain? && @theme && @theme.brand_logo.attached? %> <% logo_blob = @theme.brand_logo.blob %> <%= wicked_pdf_image_tag "data:#{logo_blob.content_type};base64,#{Base64.strict_encode64(logo_blob.download)}", width: '400px' %> <% end %> <%# 签名部分修改 %> <% if @certificate.certificate_template.signature.attached? %> <% sign_blob = @certificate.certificate_template.signature.blob %> <%= wicked_pdf_image_tag "data:#{sign_blob.content_type};base64,#{Base64.strict_encode64(sign_blob.download)}", width: '400px' %> <% end %>
方案2:生成带完整协议的绝对路径
如果不想用Base64,需要在渲染模板时强制生成绝对路径,修改控制器中render_to_string和pdf渲染的代码,补充host配置:
# controllers/admin/certificates_controller.rb def view_pdf @certificate = Certificate.find(params[:certificate_id]) # 统一配置渲染的host参数,确保生成绝对路径 render_options = { host: request.host, port: request.port, protocol: request.protocol } if !@certificate.pdf.attached? pdf = WickedPdf.new.pdf_from_string( render_to_string( template: 'admin/certificates/view_pdf.html.erb', layout: 'application.pdf.erb', **render_options ) ) @certificate.pdf.attach(io: StringIO.new(pdf), filename: "#{@certificate.path.title} - #{@certificate.user.name}.pdf", content_type: 'application/pdf') end respond_to do |format| format.html format.pdf do render( pdf: url_for(@certificate.pdf), content_type: 'application/pdf', template: 'admin/certificates/view_pdf.html.erb', page_size: 'A4', layout: 'application.pdf.erb', orientation: 'Landscape', zoom: 1, dpi: 75, disposition: 'inline', **render_options ) end end end
同时可以给Active Storage资源生成公开可访问的临时链接,避免权限拦截:
<%= wicked_pdf_image_tag @certificate.certificate_template.brand_logo.blob.signed_url(expires_in: 5.minutes), width: '400px' %>
开发环境额外检查
如果是在本地开发环境测试,需要确保config/environments/development.rb中开启静态资源服务:
config.serve_static_files = true
同时检查wkhtmltopdf版本是否支持你使用的图片格式,避免使用webp等新式格式。
内容的提问来源于stack exchange,提问作者Gustavo Borges
相关产品推荐
相关产品推荐

