Outlook addin Body#setAsync munges从Body#getAsync返回的值

Outlook addin Body#setAsync munges从Body#getAsync返回的值,outlook-addin,office-js,Outlook Addin,Office Js,我希望能够将从Body#getAsync接收到的值直接传递到Body#setAsync(使用相同的强制类型),并使Body的值保持不变。实际上,情况并非如此 示范 与预期的幂等性不同,Body#setAsync运行了大量过滤 观察到的行为 HTML字符串中具有id或class属性的任何元素,其属性值的前缀为x 从Body#getAsync返回的字符串中的某些元素包括id和class属性,这些属性对Outlook(以及我们的外接程序)似乎具有语义意义。受影响的元素包括引用的回复、签名的指示符,

我希望能够将从
Body#getAsync
接收到的值直接传递到
Body#setAsync
(使用相同的强制类型),并使Body的值保持不变。实际上,情况并非如此

示范 与预期的幂等性不同,
Body#setAsync
运行了大量过滤

观察到的行为
  • HTML字符串中具有
    id
    class
    属性的任何元素,其属性值的前缀为
    x

    • Body#getAsync
      返回的字符串中的某些元素包括
      id
      class
      属性,这些属性对Outlook(以及我们的外接程序)似乎具有语义意义。受影响的元素包括引用的回复、签名的指示符,以及主体HTML本身的包装器元素。当设置车身时,这些指示灯会变暗

    • 如果受影响的属性已具有前缀
      x\ux
      ,Outlook会添加另一个前缀。因此,每次外接程序设置主体时,这些属性值都会增加到具有相当数量的
      x\u
      前缀(例如:
      x\u x\u x\u x\u x\u x\u divtagdefaultwrapper

  • Body#getAsync
    返回的值可能包括带有数据URI的图像(在Office 365中是如此)
    Body#setAsync
    会清除这些图像的
    src
    属性,这会导致用户将图像显示为损坏图像

    • 正文中的图像一开始就不应该有数据URI——大多数电子邮件客户端不会使用数据URI呈现内联图像;它们在这些电子邮件中显示为破碎的图像

      • Outlook使用代理图像的
        src
        属性和cid:URI的
        originalsrc
        属性呈现大多数内联图像,URI引用电子邮件上具有相应
        内容ID的附件。这似乎是合理的
我们在开发外接程序时发现,实际上,
Body#setAsync
希望收到一个HTML字符串,表示Office 365中第一个属性为divtagdefaultwrapper的
id
元素内部的内容,或Outlook 2016中第一个类为WordSection1的元素内部的内容

变通办法
因此,为了解决这个问题,在调用
Body#getAsync
时,我们必须首先解析字符串并重新基址到适当的根元素,然后再通过
Body#setAsync
持久化对Body所做的任何更改。我们还不得不从身体内的元素中删除所有
id
class
属性,添加我们自己的哨兵元素来标记身体的语义重要部分(引用的回复、签名等),并为遇到数据URI的图像实现我们自己的代理。

由于单词呈现引擎的限制,我们无法保证
body.getAsync
body.setAsync
是幂等的。您在Office 365中看到的在正文中使用数据URI的内联图像的问题是我们目前正在调查的已知问题

您在哪些客户端版本中观察到了这一点?OWA?桌面Outlook?您能提供具体的版本号吗?哦,您能提供一个示例URL/HTML代码段,您正在获取/插入的代码段不是往返的吗?这是一个普遍的观察结果,适用于托管O365和内部部署Exchange上的Office 365、Outlook 2016(Windows和Mac)、Outlook 2013(Windows)。提供的示例代码可以在任何客户端中使用,包括“空”电子邮件正文。您能否提供Outlook Desktop Windows 2016和2013的特定版本号?桌面客户端Set/Get Body上的行为最近发生了很大变化,这取决于您的构建,它将影响我们的调查方式。
const { body } = Office.context.mailbox.item;
const coercionType = Office.CoercionType.Html;

// First, let's get the current body of the mailbox item.
body.getAsync(coercionType, {}, (firstResult) => {
  const previousBodyHtml = firstResult.value;

  // Now, let's set the body to the value we received.
  body.setAsync(previousBodyHtml, { coercionType }, () => {

    // Now, let's get the body again.
    body.getAsync(coercionType, {}, (secondResult) => {
      const nextBodyHtml = secondResult.value;

      // The values do not match.
      console.error(previousBodyHtml, 'does not equal', nextBodyHtml);
    });
  });
});