Python:如何在SMTP中继中向邮件头部开头插入Received头?
解决SMTP中继中在邮件头部开头插入Received:头的问题
我太懂这种被供应商拖后腿、自己动手搞SMTP中继的痛苦了!你提到用email.message_from_string()解析邮件后,add_header只能把Received头追加到末尾,没法放到头部块开头的问题,其实可以通过直接操作邮件对象的底层头部列表来搞定,完全符合SMTP标准要求。
具体实现步骤
Python的email.message.Message对象(也就是message_from_string()返回的实例),它的所有头部信息都存在_headers这个有序列表里,每个元素是(头部名称, 头部值)的元组。我们只需要把新的Received头插入到这个列表的最前面就行:
import email # 解析原始SMTP邮件内容 raw_email_content = "这里替换成你的原始邮件字符串" msg = email.message_from_string(raw_email_content) # 构造符合RFC标准的Received头内容 new_received = "from sender-server.com (sender-server.com [203.0.113.5]) by your-relay-server.net with SMTP id ABC123; Thu, 10 Oct 2024 15:45:00 +0000" # 插入到头部列表的第一个位置 msg._headers.insert(0, ('Received', new_received)) # 处理后的邮件可以转成字符串用于发送 final_email = msg.as_string()
额外提示
- 虽然
_headers看起来是私有属性,但这是Python email模块长期稳定的实现细节,用来处理头部顺序这种需求完全靠谱。 - 如果你用的是Python 3.6及以上版本,更推荐用
email.policy.default来解析邮件,得到EmailMessage对象,它有更规范的headers属性,插入方式类似:msg = email.message_from_string(raw_email_content, policy=email.policy.default) msg.headers.insert(0, ('Received', new_received)) - 一定要保证Received头的格式符合RFC 5321标准,包含来源服务器信息、时间戳等必要字段,不然后续的邮件服务器可能会拒收哦。
这样操作之后,新的Received头就会乖乖出现在邮件头部块的最开头,完美满足SMTP服务器的接收规范。
内容的提问来源于stack exchange,提问作者samwyse
相关产品推荐
相关产品推荐

