我嘗試使用 Go 和 smtp.office365.com 發送包含 pdf 檔案的電子郵件。
我找到了以下頁面,可以發送帶有 pdf 檔案的電子郵件。
https://zetcode.com/golang/email-smtp/
但是,pdf 檔案被編碼為 base64,如下圖所示。
在此處輸入影像描述
是否有任何解決方案可以像普通郵件一樣下載附加的 pdf 檔案(使用 gmail、outlook 等附加檔案)?
這是我使用的 Go 代碼。
package main
import (
"bytes"
"encoding/base64"
"errors"
"fmt"
"io/ioutil"
"log"
"net/smtp"
"strconv"
"strings"
)
type loginAuth struct {
username, password string
}
type Mail struct {
Sender string
To []string
Subject string
Body string
}
// LoginAuth is used for smtp login auth
func LoginAuth(username, password string) smtp.Auth {
return &loginAuth{username, password}
}
func (a *loginAuth) Start(server *smtp.ServerInfo) (string, []byte, error) {
return "LOGIN", []byte(a.username), nil
}
func (a *loginAuth) Next(fromServer []byte, more bool) ([]byte, error) {
if more {
switch string(fromServer) {
case "Username:":
return []byte(a.username), nil
case "Password:":
return []byte(a.password), nil
default:
return nil, errors.New("Unknown from server")
}
}
return nil, nil
}
func BuildMail(mail Mail, filename string) []byte {
var buf bytes.Buffer
buf.WriteString(fmt.Sprintf("From: %s\r\n", mail.Sender))
buf.WriteString(fmt.Sprintf("To: %s\r\n", strings.Join(mail.To, ";")))
buf.WriteString(fmt.Sprintf("Subject: %s\r\n", mail.Subject))
boundary := "my-boundary-779"
buf.WriteString("MIME-Version: 1.0\r\n")
buf.WriteString(fmt.Sprintf("Content-Type: multipart/mixed; boundary=%s\n", boundary))
buf.WriteString(fmt.Sprintf("\r\n--%s\r\n", boundary))
buf.WriteString("Content-Type: text/plain; charset=\"utf-8\"\r\n")
buf.WriteString(fmt.Sprintf("\r\n%s", mail.Body))
buf.WriteString(fmt.Sprintf("\r\n--%s\r\n", boundary))
buf.WriteString("Content-Type: text/plain; charset=\"utf-8\"\r\n")
buf.WriteString("Content-Transfer-Encoding: base64\r\n")
buf.WriteString("Content-Disposition: attachment; filename=" filename "\r\n")
buf.WriteString("Content-ID: <" filename ">\r\n\r\n")
data := readFile(filename)
b := make([]byte, base64.StdEncoding.EncodedLen(len(data)))
base64.StdEncoding.Encode(b, data)
buf.Write(b)
buf.WriteString(fmt.Sprintf("\r\n--%s", boundary))
buf.WriteString("--")
return buf.Bytes()
}
func readFile(fileName string) []byte {
data, err := ioutil.ReadFile(fileName)
if err != nil {
log.Fatal(err)
}
return data
}
func Mail_send(sender string, sender_pwd string, server string, port int, to []string, headerSubject string, body string, filename string) {
auth := LoginAuth(sender, sender_pwd)
request := Mail{
Sender: sender,
To: to,
Subject: headerSubject,
Body: body,
}
data := BuildMail(request, filename)
err := smtp.SendMail(server ":" strconv.Itoa(port), auth, sender, to, data)
if err != nil {
log.Fatalln("Error")
return
}
log.Fatalln("Success")
}
func main() {
server := "smtp.office365.com"
port := 587
sender := "my email"
password := "my pwd"
receiver := []string{"[email protected]"}
title := "TEST\r\n"
body := "test\r\n"
attach_filename := "report.pdf"
Mail_send(sender, password, server, port, receiver, title, body, attach_filename)
}
這是我收到的電子郵件。
MIME-Version: 1.0
Content-Type: multipart/mixed; boundary=my-boundary-779
--my-boundary-779
Content-Type: text/plain; charset="utf-8"
test
--my-boundary-779
Content-Type: text/plain; charset="utf-8"
Content-Transfer-Encoding: base64
Content-Disposition: attachment; filename=report.pdf
Content-ID: <report.pdf>
JVBERi0xLjMKMyAwIG9iago8PC9UeXBlIC9QYWdlCi9QYXJlbnQgMSAwIFIKL1Jlc291cmNlcyAyIDAgUgovQ29udGVudHMgNCAwIFI PgplbmRvYmoKNCAwIG9iago8PC9GaWx0ZXIgL0ZsYXRlRGVjb2RlIC9MZW5ndGggMTcyMz4 CnN0cmVhbQp4AZyaS2/dRg G9/4Vs/w
... // I omit since base64 string is too long.
AgbiAKMDAwMDAwMzc0NSAwMDAwMCBuIAowMDAwMDA0MDUzIDAwMDAwIG4gCjAwMDAwMDQxNjYgMDAwMDAgbiAKdHJhaWxlcgo8PAovU2l6ZSAxMQovUm9vdCAxMCAwIFIKL0luZm8gOSAwIFIKPj4Kc3RhcnR4cmVmCjQyNjQKJSVFT0YK
--my-boundary-779--
我希望電子郵件接收者可以直接下載附加的 pdf 檔案,而不是 base64 字串。
uj5u.com熱心網友回復:
正如懷疑的那樣,您用空行打破了郵件標題。一條完整的訊息由頭部欄位和由空行分隔的正文組成,如下所示:
From: Alice <[email protected]>
To: Bob <[email protected]>
Cc: Carol <[email protected]>
Subject: A simple example message
Date: Fri, 07 Oct 2022 16:44:37 0200
Message-ID: <[email protected]>
MIME-Version: 1.0
Content-Type: text/plain; charset=us-ascii
Hello Bob,
I think we should switch our roles.
How about you contact me from now on?
Best regards,
Alice
但是,您用換行符 ( title := "TEST\r\n") 結束主題,然后再寫一個換行符 ( buf.WriteString(fmt.Sprintf("Subject: %s\r\n", mail.Subject)))。因此,MIME-Version: 1.0被認為是訊息體的一部分而不是標頭。再試一次,不要在title. 正如 Steffen Ullrich 所指出的,您應該在發送 PDF 時替換Content-Type: text/plain; charset="utf-8"為。Content-Type: application/pdf(字符集也不是必需的。)
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/513308.html
