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

使用Rails Action Mailer发送Doc/Docx附件乱码问题求助

嘿,我来帮你搞定这个Action Mailer附件的问题!

问题出在哪?

你的核心问题是读取二进制文件时用了文本模式。File.read 默认会以文本模式打开文件,它会尝试按照系统的编码规则解析内容,但 doc 和 docx 都是二进制格式的文件(docx本质是个压缩包,里面包含XML等二进制数据),文本模式读取会破坏原始的字节结构,导致附件损坏,接收端打开自然就变成乱码或者奇怪的编码内容了。而txt是纯文本文件,文本模式读取完全没问题,所以能正常显示。

正确的实现方法

这里给你几种靠谱的解决方案,按需选择:

方法1:用二进制模式读取文件

最直接的方式是用 File.binread,它专门用来读取二进制文件,会保留原始字节:

def send_email(email, file)
  @email = email
  attachments['document.docx'] = File.binread(file.path)
  mail(from: @email, to: "aa@gmail.com", subject: "Document attachment")
end

如果你习惯用 File.read,也可以指定 mode: 'rb' 参数,效果完全一样:

attachments['document.docx'] = File.read(file.path, mode: 'rb')

方法2:传入文件对象并指定MIME类型

如果需要更精细的控制(比如明确告诉邮件客户端附件类型),可以用哈希的形式传入附件,同时确保文件以二进制模式打开:

def send_email(email, file)
  @email = email
  attachments['document.docx'] = {
    content: File.open(file.path, 'rb'),
    filename: 'document.docx',
    content_type: 'application/vnd.openxmlformats-officedocument.wordprocessingml.document'
  }
  mail(from: @email, to: "aa@gmail.com", subject: "Document attachment")
end

指定 content_type 能让邮件客户端更准确识别附件,避免出现“未知文件类型”的提示,兼容性更好。不同文件对应的MIME类型可以参考:

  • doc: application/msword
  • docx: application/vnd.openxmlformats-officedocument.wordprocessingml.document
  • txt: text/plain

方法3:处理ActiveStorage上传的文件

如果你的 file 是ActiveStorage的附件,直接用 blob.download 就好,它默认就是二进制读取,不用额外配置:

attachments['document.docx'] = file.blob.download
小提醒

以后处理非纯文本的文件(比如图片、压缩包、办公文档),都要记得用二进制模式读取,不然大概率会出现文件损坏的问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 04:06:30