简体   繁体   English

Microsoft Graph API 附件处理

[英]Microsoft Graph API Attachment handling

I seem to be having problems decoding attachments from MS Graph API.我似乎在解码来自 MS Graph API 的附件时遇到问题。 At least, that's what I think the problem is.至少,这就是我认为的问题所在。 Below is a simple JS Sample.下面是一个简单的 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();
            });
        };

I've noticed a couple oddities.我注意到了一些奇怪的地方。 The contentType seems to be wrong, PDFs are typed as application/octet-stream I would have expected application/pdf . contentType 似乎是错误的,PDF 被输入为application/octet-stream我希望application/pdf JPEG images appear to be typed correctly, however, I don't think this is the problem. JPEG 图像似乎输入正确,但是,我认为这不是问题所在。

I've tried using atob when decoding and using /$results to receive the file content in binary form.我尝试在解码时使用 atob 并使用 /$results 以二进制形式接收文件内容。

Any ideas would be great.任何想法都会很棒。

According to the documentation the Office 365 Unified API returns **base64-encoded** contents of attachments.根据文档,Office 365 Unified API 返回附件的**base64-encoded**内容。 If you were interested in processing these contents, you would first need to convert them to the original binary data.如果您对处理这些内容感兴趣,首先需要将它们转换为原始二进制数据。 Theoretically this can easily be done by calling the window.atob(base64string) function to base64-decode the contents string and then convert it to a byte array.从理论上讲,这可以通过调用window.atob(base64string)函数对内容字符串进行base64-decode ,然后将其转换为字节数组来轻松完成。

Unfortunately if you would try to open the file after such processing you would find out that it's broken and its contents are unreadable.不幸的是,如果您在这样的处理后尝试打开文件,您会发现它已损坏并且其内容无法读取。

It turns out that attachments contents returned by the Office 365 Unified API are base64-encoded not once but twice!事实证明,Office 365 Unified API 返回的附件内容不是一次而是两次进行 base64 编码! So in order to get the binary contents you have to wrap the window.atob call with another window.atob call.所以,为了得到的二进制内容,你必须包裹window.atob与其他呼叫window.atob电话。 This will allow you to get the binary contents of your attachment just as expected:这将允许您按预期获取附件的二进制内容:

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;
}

Additional reference:补充参考:

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

Try and see if it helps.试试看是否有帮助。

Thanks @Mohit Verma, you helped get me back on track.谢谢@Mohit Verma,你帮助我回到正轨。 However, the double decoding didn't seem to be the exact issue as the following code throws a然而,双重解码似乎并不是确切的问题,因为以下代码抛出了一个

Uncaught DOMException: Failed to execute 'atob' on 'Window': The string to be decoded is not correctly encoded. Uncaught DOMException: Failed to execute 'atob' on 'Window': 要解码的字符串未正确编码。

        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();
            });
        };

However, this code works due to the fact that the results.contentBytes is converted to a ByteArray which is what the Blob constructor was expecting.但是,由于 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();
            });
        };

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM