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

