9

我在解码使用 Gmail API 收到的电子邮件的消息正文时遇到严重问题。我想获取消息内容并将内容放在一个 div 中。我正在使用 base64 解码器,我知道它不会解码以不同方式编码的电子邮件,但我不确定如何检查电子邮件以决定使用哪个解码器 - 说它们是 utf-8 编码的电子邮件被成功解码base64 解码器,但不是 utf-8 解码器。

几天来我一直在研究电子邮件解码,我了解到我在这里有点不合群。我以前没有做太多关于电子邮件编码的工作。这是我用来获取电子邮件的代码:

gapi.client.load('gmail', 'v1', function() {
var request = gapi.client.gmail.users.messages.list({
  labelIds: ['INBOX']
});
request.execute(function(resp) {
  document.getElementById('email-announcement').innerHTML = '<i>Hello! I am reading your <b>inbox</b> emails.</i><br><br>------<br>';
  var content = document.getElementById("message-list");
  if (resp.messages == null) {
    content.innerHTML = "<b>Your inbox is empty.</b>";
  } else {
    var encodings = 0;
    content.innerHTML = "";
    angular.forEach(resp.messages, function(message) {
      var email = gapi.client.gmail.users.messages.get({
      'id': message.id
      });
      email.execute(function(stuff) {
        if (stuff.payload == null) {
          console.log("Payload null: " + message.id);
        }
        var header = "";
        var sender = "";
        angular.forEach(stuff.payload.headers, function(item) {
          if (item.name == "Subject") {
            header = item.value;
          }
          if (item.name == "From") {
            sender = item.value;
          }
        })
        try {
          var contents = "";
          if (stuff.payload.parts == null) {
            contents = base64.decode(stuff.payload.body.data);
          } else {
            contents = base64.decode(stuff.payload.parts[0].body.data);
          }
          content.innerHTML += '<b>Subject: ' + header + '</b><br>';
          content.innerHTML += '<b>From: ' + sender + '</b><br>';
          content.innerHTML += contents + "<br><br>";
        } catch (err) {
          console.log("Encoding error: " + encodings++);
        }
      })
    })
  }
 });
});

我正在执行一些检查和调试,所以有剩余console.log的和其他一些仅用于测试的东西。不过,您可以在这里看到我正在尝试做的事情。

解码我从 Gmail API 中提取的电子邮件的最佳方法是什么?我是否应该尝试将电子邮件放入与电子邮件<script>的编码内容匹配的属性中charsettype我相信我记得 charset 只适用于src我不会在这里拥有的属性。有什么建议么?

4

7 回答 7

23

对于我正在编写的原型应用程序,以下代码适用于我:

var base64 = require('js-base64').Base64;
// js-base64 is working fine for me.

var bodyData = message.payload.body.data;
// Simplified code: you'd need to check for multipart.

base64.decode(bodyData.replace(/-/g, '+').replace(/_/g, '/'));
// If you're going to use a different library other than js-base64,
// you may need to replace some characters before passing it to the decoder.

注意:这些点没有明确记录,可能是错误的:

  1. users.messages: getAPI默认返回“已解析的正文内容”。此数据似乎总是以 UTF-8 和 Base64 编码,而不管Content-TypeandContent-Transfer-Encoding标头如何。

    例如,我的代码在解析带有以下标头的电子邮件时没有问题:Content-Type: text/plain; charset=ISO-2022-JP, Content-Transfer-Encoding: 7bit.

  2. Base64 编码的映射表因各种实现而异。Gmail API 使用-_作为表格的最后两个字符,由RFC 4648的“URL 和文件名安全字母表” 1定义。

    检查您的 Base64 库是否使用不同的映射表。如果是这样,请将这些字符替换为您的库接受的字符,然后再将正文传递给解码器。


1文档中有一条支持线:“原始”格式返回“作为 base64url 编码字符串的正文内容”。(谢谢埃里克!)

于 2014-09-28T14:16:28.177 回答
4

使用 atob 解码 JavaScript 中的消息(请参阅ref)。要访问您的消息有效负载,您可以编写一个函数:

var extractField = function(json, fieldName) {
  return json.payload.headers.filter(function(header) {
    return header.name === fieldName;
  })[0].value;
};
var date = extractField(response, "Date");
var subject = extractField(response, "Subject");

从我之前的SO Question

var part = message.parts.filter(function(part) {
  return part.mimeType == 'text/html';
});
var html = atob(part.body.data);

如果上述内容不能 100% 正确解码,@cgenco 对此答案的评论可能适用于您。在这种情况下,做

var html = atob(part.body.data.replace(/-/g, '+').replace(/_/g, '/'));
于 2015-02-20T05:22:45.707 回答
2

这是解决方案:Gmail API - “Users.messages: get” 方法响应 message.payload.body.data 将 base64 数据分开,用“-”符号分隔。它不是完整的 base64 编码文本,而是 base64 文本的一部分。您必须尝试解码其中的每一部分,或者通过联合制作一个单声道字符串并替换“-”符号。在此之后,您可以轻松地将其解码为人类文本。您可以在此处手动检查每个部分https://www.base64decode.org

于 2017-12-31T19:51:55.820 回答
2

这一点我也很恼火。我通过查看 VSCode 的扩展发现了一个解决方案。解决方案非常简单:

const body = response.data.payload.body; // the base64 encoded body of a message
 body = Buffer.alloc(
        body.data.length,
        body.data,
        "base64"
      ).toString();  // the decoded message

当我使用gmail.users.messages.get()Gmail API 调用时,它对我有用。

于 2019-11-24T20:31:19.907 回答
1

请使用网络安全解码器来解码 gmail 电子邮件和附件。当我只使用 base64decoder 时,我得到了空白页,不得不使用这个:https ://www.npmjs.com/package/urlsafe-base64

于 2018-02-19T05:51:51.847 回答
0

我可以使用https://simplycalc.com/base64-decode.php上的另一个工具轻松解码

在 JS 中:https ://www.npmjs.com/package/base64url

在 Python 3 中:

import base64
base64.urlsafe_b64decode(coded_string)
于 2019-03-31T06:14:54.720 回答
0

感谢@ento 的回答。我进一步解释了为什么在解码之前需要将“-”和“_”字符替换为“+”和“/”。

Wiki Base64 Variants 汇总表显示:

  • RFC 4648第 4 节base64(标准):使用 '+' 和 '/'
  • RFC 4648第 5 节base64url(URL 安全和文件名安全标准):使用 '-' 和 '_'

简而言之,Gmail API 使用base64url(urlsafe)格式('-' 和 '_'),但 JavaScript atob 函数或其他 JavaScript 库使用base64(标准)格式('+' 和 '/')。

对于 Gmail API,文档说正文使用 base64url 格式,请参见以下链接:

对于 Web atob/btoa 标准,请参见以下链接:

于 2020-10-18T23:00:23.023 回答