问题描述
我使用 gapi 发送电子邮件。接收器正确接收它们,但是当我开始查看“已发送”框时,它们看起来就像是中文乱码。喜欢this image
更具体地说,只有当我使用非 Gmail 应用程序时,它才会看起来像这样。因此,如果我在 Gmail 中查看我的“已发送”框,它看起来不错,但是如果我使用 Outlook 或如果我使用我的 Android 的默认邮件应用程序并将其与我的 gmail 帐户连接并查看“已发送”文件夹,它就完全搞砸了。显然它与编码有关,但显然 gmail 设法修复它而其他应用程序没有。
async sendMail(email,files) {
//create cc and bcc string if needed
let ccStr = `Cc: ${email.cc}\r\n`
let bccStr = `Bcc: ${email.bcc}\r\n`
//create attachment if needed
let attachStr = await this.createAttachmentStr(files)
attachStr = `${attachStr}\r\n\r\n`
//create the message
let message = 'Content-Type: multipart/mixed; boundary="#split-part#"\r\n' +
'MIME-Version: 1.0\r\n' +
`To: ${email.to}\r\n` +
`From: ${email.from}\r\n` +
ccStr +
bccStr +
`Subject: ${email.subject}\r\n\r\n` +
'--#split-part#\r\n' +
'Content-Type: text/html; charset="UTF-8"\r\n' +
'MIME-Version: 1.0\r\n' +
'Content-transfer-encoding: base64\r\n\r\n' +
`${email.message}\r\n\r\n` +
`${attachStr}` +
'--#split-part#--'
//base64url encode
const encodedMessage = btoa(unescape(encodeURIComponent(message))).replace(/\+/g,'-').replace(/\//g,'_').replace(/=+$/,'')
//send to api
gapi.client["gmail"].users.messages.send({
'userId': 'me','resource': {
'raw': encodedMessage,"payload": {
"mimeType": 'multipart/mixed'
},'threadId': email.id
}
}).then(async response => {
//do some stuff after
})
}
那里使用的方法称为基于 FileList 的 createAttachmentStr:
createAttachmentStr(files: FileList): Promise<string> {
return new Promise<string>((resolve) => {
let attachStr = ""
//initialize counter
let count = 0
//loop through each file
if (files && files.length > 0) {
Array.from(files).forEach(async file => {
//convert file to datastrings
let dataStr = await this.readFileContent(file)
//get file info
let fileName = file.name
let contentType = file.type
//create message str
attachStr += '--#split-part#\r\n' +
`Content-Type: ${contentType}\r\n` +
'MIME-Version: 1.0\r\n' +
'Content-transfer-encoding: base64\r\n' +
`Content-disposition: attachment; filename="${fileName}"\r\n\r\n` +
`${dataStr}\r\n\r\n`
//increase the counter
count++
if (count === files.length) {
resolve(attachStr);
}
});
}
else resolve("")
});
}
请注意,这并不总是发生,实际上很少发生,但我无法弄清楚究竟是什么触发了它。似乎与一些带有特定附件的电子邮件有关。
我对这个有点迷茫,所以感谢任何帮助
解决方法
既然你提到它似乎与特定的附件有关,则表明问题与电子邮件的内容类型标题有关:
Content-Type: text/html; charset="UTF-8"
意思是其中一个(或两者):
-
您的某些附件(可能还有
email.message
)不是 HTML 文件(这也意味着不应将邮件的这些部分传递给encodeURIComponent
)。 -
dataStr
不是 utf-8 编码的,这意味着this.readFileContent(file)
将文件读取为 utf-8 编码的文件,而它实际上有一些其他编码。
另一种选择是某些附件文件的 contentType
构造了一个错误的附件头(即,它与实际文件类型不对应),部分(例如,缺少 charset="UTF-8"
部分) ) 或无效(即不存在的内容类型),在以下行中:
`Content-Type: ${contentType}\r\n`