【问题标题】:Microsoft Graph API Attachment handlingMicrosoft Graph API 附件处理
【发布时间】:2020-04-11 13:29:42
【问题描述】:

我似乎在从 MS Graph API 解码附件时遇到问题。至少,这就是我认为的问题所在。下面是一个简单的 JS 示例。

        local.downloadAttachment = function (data) {
            $.get("https://graph.microsoft.com/v1.0/me/messages/" + self.EmailID() + "/attachments/" + data.id, null, function (results) {
                var bytes = new Uint8Array(results.contentBytes); // pass your byte response to this constructor
                var blob = new Blob([bytes], { type: results.contentType });// change resultByte to bytes

                //Alt method, also doesn't work but seems a lot closer to the right solution.
                //var altBytes = $.base64.decode(results.contentBytes);
                //var blob = new Blob([altBytes], { type: results.contentType });

                var link = document.createElement('a');
                link.href = window.URL.createObjectURL(blob);
                link.download = results.name;
                link.click();
            });
        };

我注意到了一些奇怪的地方。 contentType 似乎是错误的,PDF 被键入为 application/octet-stream 我本来期望 application/pdf。 JPEG 图像似乎输入正确,但我认为这不是问题。

我尝试在解码时使用 atob 并使用 /$results 以二进制形式接收文件内容。

任何想法都会很棒。

【问题讨论】:

    标签: javascript microsoft-graph-api exchangewebservices azure-ad-graph-api microsoft-graph-mail


    【解决方案1】:

    根据文档,Office 365 统一 API 返回附件的 **base64-encoded** 内容。如果您对处理这些内容感兴趣,您首先需要将它们转换为原始二进制数据。理论上,这可以通过调用window.atob(base64string) 函数来轻松完成base64-decode 内容字符串,然后将其转换为字节数组。

    不幸的是,如果您在经过此类处理后尝试打开文件,您会发现它已损坏并且其内容无法读取。

    事实证明,Office 365 统一 API 返回的附件内容不是一次而是两次采用 base64 编码!因此,为了获得二进制内容,您必须将 window.atob 调用与另一个 window.atob 调用包装起来。这将允许您按预期获取附件的二进制内容:

    function getBinaryFileContents(base64FileContents) {
      // atob has to be called twice because the FileAttachment.ContentBytes property
      // return by the attachments endpoint is base64-encoded twice
      var raw = window.atob(window.atob(base64FileContents));
      var rawLength = raw.length;
      var array = new Uint8Array(new ArrayBuffer(rawLength));
    
      for(var i = 0; i < rawLength; i++) {
        array[i] = raw.charCodeAt(i);
      }
    
      return array;
    }
    

    补充参考:

    https://blog.mastykarz.nl/office-365-unified-api-mail/

    试试看是否有帮助。

    【讨论】:

      【解决方案2】:

      感谢@Mohit Verma,您帮助我重回正轨。但是,双重解码似乎不是确切的问题,因为以下代码会引发

      未捕获的 DOMException:无法在“窗口”上执行“atob”: 要解码的字符串编码不正确。

              local.downloadAttachment = function (data) {
                  $.get("https://graph.microsoft.com/v1.0/me/messages/" + self.EmailID() + "/attachments/" + data.id, null, function (results) {
                      var raw = window.atob(window.atob(results.contentBytes));
                      var rawLength = raw.length;
                      var array = new Uint8Array(new ArrayBuffer(rawLength));      // pass your byte response to this constructor
      
                      for (var i = 0; i < rawLength; i++) {
                          array[i] = raw.charCodeAt(i);
                      }
      
                      var blob = new Blob([array], { type: results.contetType });
      
                      var link = document.createElement('a');
                      link.href = window.URL.createObjectURL(blob);
                      link.download = results.name;
                      link.click();
                  });
              };
      

      但是,由于 results.contentBytes 被转换为 Blob 构造函数所期望的 ByteArray,因此此代码有效。

              local.downloadAttachment = function (data) {
                  $.get("https://graph.microsoft.com/v1.0/me/messages/" + self.EmailID() + "/attachments/" + data.id, null, function (results) {
                      var raw = window.atob(results.contentBytes);
                      var rawLength = raw.length;
                      var array = new Uint8Array(new ArrayBuffer(rawLength));      // pass your byte response to this constructor
      
                      for (var i = 0; i < rawLength; i++) {
                          array[i] = raw.charCodeAt(i);
                      }
      
                      var blob = new Blob([array], { type: results.contetType });
      
                      var link = document.createElement('a');
                      link.href = window.URL.createObjectURL(blob);
                      link.download = results.name;
                      link.click();
                  });
              };
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2022-01-06
        • 1970-01-01
        • 2017-07-01
        • 2019-02-27
        • 1970-01-01
        • 2019-07-16
        相关资源
        最近更新 更多