Go解析MIME邮件遇格式错误,求将时间信息放入主题/自定义头
解决Go net/mail解析邮件的格式错误及相关需求
错误原因
net/mail包严格遵循MIME邮件规范,要求所有头部行必须是字段名: 值的格式。你的邮件内容中,Friday, September这行没有冒号,被包识别为无效的头部字段,因此抛出malformed MIME header: missing colon错误。
解决方法
1. 将时间信息整合到主题或自定义头部
方案一:合并到Subject字段
修改邮件内容的Subject行,把时间信息附加进去,确保头部格式合规:
msg := `Date: Mon, 23 Jun 2015 11:40:36 -0400 From: Gopher <from@example.com> To: Another Gopher <to@example.com> Subject: Gophers at Gophercon | Friday, September 21st 1-3pm room 32c2 Message body `
解析后可直接通过header.Get("Subject")获取包含时间的完整主题。
方案二:添加自定义头部
新增一个符合格式的自定义头部字段(比如X-Event-Details)来存放时间信息:
msg := `Date: Mon, 23 Jun 2015 11:40:36 -0400 From: Gopher <from@example.com> To: Another Gopher <to@example.com> Subject: Gophers at Gophercon X-Event-Details: Friday, September 21st 1-3pm room 32c2 Message body `
解析后通过header.Get("X-Event-Details")即可单独提取时间信息。
2. 将时间信息移至邮件正文
如果希望时间信息作为正文的一部分,只需将其放到头部与正文的分隔空行之后:
msg := `Date: Mon, 23 Jun 2015 11:40:36 -0400 From: Gopher <from@example.com> To: Another Gopher <to@example.com> Subject: Gophers at Gophercon Friday, September 21st 1 - 3pm room 32c2 Message body `
此时net/mail会将这些行识别为正文内容,解析流程正常执行。
3. 缩进文本中的对应行
如果需要对时间行进行缩进处理,可以在构造邮件内容时直接添加空格,或者通过代码遍历行批量修改:
// 原始时间行切片 timeLines := []string{"Friday, September", "21st", "1 - 3pm", "room 32c2"} // 缩进处理:每行前加4个空格 indentedLines := make([]string, len(timeLines)) for i, line := range timeLines { indentedLines[i] = " " + line } // 拼接进邮件正文 msg := fmt.Sprintf(`Date: Mon, 23 Jun 2015 11:40:36 -0400 From: Gopher <from@example.com> To: Another Gopher <to@example.com> Subject: Gophers at Gophercon %s Message body `, strings.Join(indentedLines, "\n"))
完整可运行代码示例
package main import ( "fmt" "io" "log" "net/mail" "strings" ) func main() { // 使用自定义头部的示例 msg := `Date: Mon, 23 Jun 2015 11:40:36 -0400 From: Gopher <from@example.com> To: Another Gopher <to@example.com> Subject: Gophers at Gophercon X-Event-Details: Friday, September 21st 1-3pm room 32c2 Message body ` r := strings.NewReader(msg) m, err := mail.ReadMessage(r) if err != nil { log.Fatal(err) } header := m.Header fmt.Println("Date:", header.Get("Date")) fmt.Println("From:", header.Get("From")) fmt.Println("To:", header.Get("To")) fmt.Println("Subject:", header.Get("Subject")) fmt.Println("Event Details:", header.Get("X-Event-Details")) body, err := io.ReadAll(m.Body) if err != nil { log.Fatal(err) } fmt.Printf("\nBody:\n%s", body) }
内容的提问来源于stack exchange,提问作者Ricardo Ruiz
相关产品推荐
相关产品推荐

