Gmail API不尊重主题中的UTF编码

时间:2014-12-29 20:45:57

标签: node.js encoding utf-8 google-schemas google-api-nodejs-client

在我正在帮助开发的应用中,我们添加了用户邀请其他用户和个性化邀请电子邮件的功能,然后通过Gmail的API发送。我使用base64编码它作为文档状态,我们发送的电子邮件格式正确,因为它们正确地发送给收件人。这适用于使用英语输入的美国用户,但是有些用户发送的电子邮件包含非ASCII字符(例如希伯来语),其电子邮件在发送时出现乱码。

我测试了它并确保我们正确编码 - 我们通过执行new Buffer(emailString).toString('base64')对其进行编码,然后通过执行encoded.replace(/\+/g, '-').replace(/\//g, '_').replace(/=+$/, '')替换某些字符。我创建了一个随机的Cyrillic 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中实际发送时,标题会变得混乱并出现乱码:

Actual email sent

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

3 个答案:

答案 0 :(得分:6)

我遇到了同样的问题,我收到了以下信息:Using UTF-8 charactors in an e-mail mail subject

所以我用=?utf-8?B?${convertToBase64(subject)}?=替换我的主题,效果很好。

${}是一个变量模板,如果您想将Нык ан мюндй конвынёры设置为主题,它将如下所示:

=?utf-8?B?0J3Ri9C6INCw0L0g0LzRjtC90LTQuSDQutC-0L3QstGL0L3RkdGA0Ys?=

答案 1 :(得分:3)

根据RFC标准,电子邮件主题必须为US ASCII(7位)。

如果您想在主题中使用非美国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 / RFC2822(https://www.ietf.org/rfc/rfc0822.txt)第2.2节标题字段说:

  

标题字段是由字段名称组成的行,后跟冒号     (&#34;:&#34;),后跟字段正文,并由CRLF终止。一个字段     名称必须由可打印的US-ASCII字符组成(即,     除了之外,其值为33到126之间的字符     结肠。 字段正文可以由任何US-ASCII字符组成,     CR和LF除外。但是,字段正文可能包含CRLF     用于标题&#34;折叠&#34;和&#34;展开&#34;如章节所述     2.2.3。所有的字体都必须符合中描述的语法     本标准的第3和第4节。

US-ASCII是指原始的7位ASCII编码(0-127)。

答案 2 :(得分:0)

测试了@Oboo Chin的解决方案,它目前正在起作用。

对于PHP,您可以使用:

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