Rails中在邮件正文发送S3文件报错,求助实现附件嵌入需求
问题分析与解决
错误原因
Errno::ENOENT 错误是因为你调用了 File.read(URI.parse(@path)) —— File.read 仅能读取本地文件系统内的文件,无法直接读取远程S3 URL指向的内容,因此触发了“找不到文件或目录”的报错。
解决方案
1. 修正正文内容的获取逻辑
如果要在正文中使用S3文件的内容(仅适用于文本类文件,PDF无法直接作为纯文本邮件正文显示),需通过HTTP请求获取远程内容,替代File.read:
@path = s3_url # 读取S3文件的远程内容 file_content = HTTParty.get(@path).body attachments["output.pdf"] = { mime_type: "application/pdf", content: file_content } mail(to: 'xyz@gmail.com', subject: "Test Attachment", body: file_content)
2. 实现附件嵌入正文(PDF内嵌显示)
如果是想把PDF作为内嵌资源展示在邮件正文中(仅部分主流邮件客户端支持),需要通过CID(Content-ID)关联附件与HTML正文:
@path = s3_url file_content = HTTParty.get(@path).body # 添加内嵌附件并指定唯一CID attachments.inline["output.pdf"] = { mime_type: "application/pdf", content: file_content, content_id: "<pdf_embed_cid>" # 自定义CID,需包含尖括号格式 } # 发送HTML格式邮件,在正文中引用CID资源 mail(to: 'xyz@gmail.com', subject: "Test Attachment", content_type: "text/html") do |format| format.html do "<p>以下是内嵌的PDF文件:</p><embed src='cid:pdf_embed_cid' type='application/pdf' width='100%' height='600px'>".html_safe end end
注意事项
- 并非所有邮件客户端都支持PDF内嵌显示,部分客户端会自动将其转为普通附件。
- 确保S3 URL是公开可访问的;如果是私有S3资源,需在HTTP请求中携带有效的权限签名。
内容的提问来源于stack exchange,提问作者smith
相关产品推荐
相关产品推荐

