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

Rails项目中Prawn加载外部图片报错:No such file or directory @ rb_sysopen

解决Prawn加载外部图片报错No such file or directory @ rb_sysopen的问题

问题核心

这个错误的本质是open(@foo.image.url)没有正确解析成外部资源的IO流,反而被当成本地文件路径查找,因此触发了文件不存在的错误。常见诱因有两个:

  • @foo.image.url返回的是相对路径而非完整外部URL(比如仅返回/uploads/image.jpg,而非https://yourdomain.com/uploads/image.jpg)
  • open调用未正确处理二进制资源,返回的对象不符合Prawn的image方法要求

解决方案

1. 确保图片URL是完整绝对路径

先在控制台打印@foo.image.url,确认输出是带http://或https://的完整外部地址。如果是相对路径,需根据你使用的附件上传gem生成绝对URL:

# Active Storage 示例:
absolute_image_url = rails_blob_url(@foo.image, only_path: false)
# CarrierWave 示例:
absolute_image_url = @foo.image.url(host: Rails.application.config.action_controller.default_url_options[:host])

2. 正确使用open加载外部图片

需以二进制模式打开外部资源,同时确保返回的IO对象能被Prawn识别。修正后的PDF类代码:

class ExamplePdf < Prawn::Document
  require 'open-uri'

  def initialize(foo)
    super()
    @foo = foo
    letter
  end

  def letter
    # 获取完整绝对图片URL(根据你的附件gem调整)
    absolute_image_url = rails_blob_url(@foo.image, only_path: false)

    # 以二进制模式打开外部资源并传递给Prawn
    URI.open(absolute_image_url, 'rb') do |image_io|
      image image_io, scale: 0.5
    end
  end
end

注:Ruby 2.6+推荐用URI.open替代直接open,避免命名冲突同时提升安全性。

3. 额外排查点

  • 检查服务器是否能正常访问该外部URL(比如防火墙、代理设置限制)
  • 如果使用Active Storage,确保config.active_storage.service配置的存储服务(如S3)URL是公开可访问的

控制器调用无需修改

你当前的控制器代码逻辑正常,保持原样即可:

pdf = CombinePDF.new
letter = ExamplePdf.new(@foo).render
pdf << CombinePDF.parse(letter)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.24 16:12:11