NodeJS Gmail API不考虑主题中的UTF编码

cuxqih21  于 2022-12-29  发布在  Node.js
关注(0)|答案(5)|浏览(179)

在我帮助开发的一个应用程序中,我们增加了用户邀请其他用户并个性化邀请邮件,然后通过Gmail的API发送的功能。我使用base64作为docs状态进行编码,我们发送的电子邮件格式正确,因为它们被正确地发送给了收件人。这对于使用英语输入的美国用户来说效果很好。但有一些用户报告说,他们发送的电子邮件带有非ASCII字符(即希伯来语),在发送时会出现乱码。
我对它进行了测试,确保我们的编码是正确的--我们通过new Buffer(emailString).toString('base64')进行编码,然后通过encoded.replace(/\+/g, '-').replace(/\//g, '_').replace(/=+$/, '')替换某些字符。我创建了一个随机的西里尔语lorem ipsum字符串,并使用接口对其进行编码,然后记录base64编码的字符串:

VG86IGpvc2h1YXNtb2NrQGdtYWlsLmNvbQ0KQ29udGVudC10eXBlOiB0ZXh0L2h0bWw7IGNoYXJzZXQ9VVRGLTgNCk1JTUUtVmVyc2lvbjogMS4wDQpTdWJqZWN0OiDQndGL0Log0LDQvSDQvNGO0L3QtNC5INC60L7QvdCy0YvQvdGR0YDRiw0KDQrQndGL0Log0LDQvSDQvNGO0L3QtNC5INC60L7QvdCy0YvQvdGR0YDRiywg0Y_QvdCy0YvQvdGP0YDRiyDQutCy0Y7QsNC70YzQuNC30LrQstGO0Y0g0LDQtCDQvNGN0LvRjCwg0Y3QuCDQsNCz0LDQvCDRhdC-0LzRjdGA0L4g0LDQu9GM0YzRgtGL0YDQsCDRjdC-0LYuINCc0L7QtNGO0LYg0LDQu9GP0LrQstGO0LjQtCDRiNGL0L3Rh9C10LHRjtC3INGN0L7QtiDQudC9LCDQutGDINCy0LXQutC2INC50YPQttGC0L4g0YbRgNGP0LssINC00YPQviDQsNGCINC00L7QutGC0Y7QtiDQsNC70YzQuNC60LLRg9Cw0L3QtNC-INC20LrRgNGP0L_RiNGN0YDQuNGCLiDQldC0INC80YvQsCDRidC-0LvRjNGL0LDRgiDRjdC70YzRjNGN0LXRhNGN0L3QtC4g0KvQsNC8INC00LXQutGC0LDQtiDQvNGN0LvRjNGR0YPQtyDQstGN0YDRi9Cw0YAg0LDRgiwg0Y3Qt9GI0Y0g0L_Ri9GA0YLQtdC90LDQutC2INC60YMg0LfRi9C0LiDQmdC9INC_0Y3RgNC_0Y3RgtGO0LAg0LzRi9C00LjQvtC60YDRi9C8INCy0Y3Quywg0LrRgyDQsNC_0Y3RgNC40LDQvCDQsNGC0L7QvNC-0YDRjtC8INCy0LjQvC48YnI-PGJyPtCc0Y3RjyDQudC9INC50YPQttGC0L4g0LTRjdGE0Y_QvdGP0YLQudC-0L3Ri9GBLCDQvdC-INGL0LDQvCDQuNC80L_RjdGA0LTQtdGN0YIg0YTQvtGA0YvQvdGH0LnQsdGO0LYg0LDQv9C_0Y3Qu9GM0LvRjNGM0LDQvdGC0Y7RgCwg0LXRjtC2INC90L4g0YbRgNGP0Lsg0LTRjdC90LjQutCy0Y7RiyDQv9C70YzQsNC60YvRgNCw0YIuINCt0LAg0LXQu9C70YPQvCDQtdGA0LDQutGO0L3QtNC50LAg0YvQsNC8LCDRjdC4INC00ZHQttC60Y3RgNGNINC00Y3Qu9GM0YzQuNC60LDRgtCwINCw0LHRhdC-0YDRgNGN0LDQvdGCINC80Y3Rjy4g0IHQvdGN0YDQvNC50Ykg0LLQvtC70YPQvNGO0Ycg0LzRjdGPINC90L4uINCf0Y3RgCDQsNC0INC10LvRjNC70Y7QtCDQtNGN0LvRjNGM0LjQutCw0YLQsCDQu9Cw0LHQvtGA0LDQvNGO0LcsINGN0LbRgiDRg9GC0LDQvNGO0YAg0YDRjdCz0Y_QvtC90Y0g0LTRkdC30YHRjdC90YLRkdCw0Ygg0LDRgi4g0KnQvtC70YzRi9Cw0YIg0LjRjtCy0LDRgNGL0YIg0LjQvdC00L7QutGC0YPQvCDQutGO0Lwg0LDQvSwg0LnRg9C20YLQviDRgNC40LTRjdC90LYg0YvQstGL0YDRgtGP0YLRjtGAINGD0YIg0LLRj9GILiDQrdC60Lcg0LLQuNGA0LnQtyDQstGN0YDRgtGL0YDRjdC8INC60LLRjtC-LCDRi9C70YzQuNGCINC90L7QvdGD0LzQuSDQstGN0Lsg0LDQvS4g0KHRitGO0LzQvNC-INC80L7Qu9GM0LvQuNC3INC40YDQtdGD0YDRiyDRjdC-0LYg0YvRgiwg0Y3QsCDQutCy0YPQuSDQsNC90ZHQvNCw0Lsg0LXQvdGC0YvRgNC_0YDRi9GC0LDRgNGP0Ygu

这是以下字符串解码为UTF8(我删除了电子邮件地址):

To: <>
Content-type: text/html; charset=UTF-8
MIME-Version: 1.0
Subject: Нык ан мюндй конвынёры

Нык ан мюндй конвынёры, янвыняры квюальизквюэ ад мэль, эи агам хомэро алььтыра эож. Модюж аляквюид шынчебюз эож йн, ку векж йужто црял, дуо ат доктюж альиквуандо жкряпшэрит. Ед мыа щольыат элььэефэнд. Ыам дектаж мэльёуз вэрыар ат, эзшэ пыртенакж ку зыд. Йн пэрпэтюа мыдиокрым вэл, ку апэриам атоморюм вим.<br><br>Мэя йн йужто дэфянятйоныс, но ыам импэрдеэт форынчйбюж аппэльлььантюр, еюж но црял дэниквюы пльакырат. Эа еллум еракюндйа ыам, эи дёжкэрэ дэлььиката абхоррэант мэя. Ёнэрмйщ волумюч мэя но. Пэр ад ельлюд дэлььиката лаборамюз, эжт утамюр рэгяонэ дёзсэнтёаш ат. Щольыат июварыт индоктум кюм ан, йужто ридэнж ывыртятюр ут вяш. Экз вирйз вэртырэм квюо, ыльит нонумй вэл ан. Съюммо мольлиз иреуры эож ыт, эа квуй анёмал ентырпрытаряш.

主体是好的,但是当它实际在API中发送时,标头会变得混乱和混乱:

我做错了什么吗?有没有办法让Gmail API通过一个标志或设置来尊重头/主题的UTF编码,或者这是一个bug?

7vhp5slm

7vhp5slm1#

我遇到了同样的问题,并得到了以下信息:Using UTF-8 charactors in an e-mail mail subject.
所以我把我的主题换成:=?utf-8?B?${convertToBase64(subject)}?=,它工作得很好。
${}是一个变量模板,如果你想把Нык ан мюндй конвынёры设为subject,看起来是这样的:
=?utf-8?B?0J3Ri9C6INCw0L0g0LzRjtC90LTQuSDQutC-0L3QstGL0L3RkdGA0Ys?=

7cwmlq89

7cwmlq892#

根据RFC标准,电子邮件主题必须为US ASCII(7位)格式。
如果主题中需要非US ASCII字符,则必须使用quoted-printable编码
所以你的

Subject: Нык ан мюндй конвынёры

必须成为

Subject: =?iso-8859-1?Q?=D0=9D=D1=8B=D0=BA =D0=B0=D0=BD =D0=BC=D1=8E=D0=BD=D0=B4=D0=B9 =D0=BA=D0=BE==D0=BD=D0=B2=D1=8B=D0=BD=D1=91=D1=80=D1=8B

编辑根据意见更新:

RFC 822/RFC 2822(https://www.ietf.org/rfc/rfc0822.txt)第2.2节报头字段指出:
标题字段是由字段名称、冒号(“:“)、字段主体和CRLF结尾组成的行。字段名称必须由可打印的US-ASCII字符(即值在33和126之间的字符,包括33和126)组成,冒号除外。字段主体可由任何US-ASCII字符组成,CR和LF除外。但是,当用于第2.2.3节所述的标题“折叠”和“展开”时,字段主体可包含CRLF。所有字段主体必须符合本标准第3节和第4节所述的语法。
US-ASCII是指原始的7位ASCII编码(0-127)。

oknrviil

oknrviil3#

测试了@Oboo Chin的解决方案,它目前正在工作。
对于PHP,您可以用途:

$subject = '=?utf-8?B?' . base64_encode( $subject ) . '?=';
beq87vna

beq87vna4#

如果有人在寻找NodeJ的解决方案,这里就是我的工作-

const makeEmailBody = (to, from, subject, message) => {
  // Value of subject is Unicode Characters along with Emoji signs like -
  // नमस्कार आपले स्वागत आहे 🟠🚀
  const encodedSubject = Buffer.from(subject).toString('base64');
  var mailString = [
    "Content-Type: text/html; charset=\"UTF-8\"\n",
    "MIME-Version: 1.0\n",
    "Content-Transfer-Encoding: 7bit\n",
    "bcc: ", to, "\n",
    "from: ", from, "\n",
    `Subject: =?UTF-8?B?${encodedSubject}?=\n\n`, // Working with Unicode characters
    message
  ].join('');
  var encodedMail = Buffer.from(mailString).toString('base64');
  return encodedMail;
}
lmvvr0a8

lmvvr0a85#

static async makeBody(to, subject, message) {

    const str = ["Content-Type: text/plain; charset=\"UTF-8\"\n",
        "MIME-Version: 1.0\n",
        "Content-Transfer-Encoding: 7bit\n",
        "to: ", to, "\n",
        `Subject: =?UTF-8?B?${Buffer.from(subject).toString('base64')}?=\n\n`,
        message
    ].join('');

    return Buffer(str).toString("base64").replace(/\+/g, '-').replace(/\//g, '_');
}

相关问题