如何替换/更新字符串中的特定HTML标记

问题描述

我有一个使用React和TypeScript的SPFx现代Webpart。我正在使用Microsoft Graph API从Teams Channel获取消息:

  this.context.msGraphClientFactory
    .getClient()
    .then((client: MSGraphClient): void =>{
      client
        .api(`/teams/${teamId}/channels/${channelId}/messages/delta`)
        .filter(maxPastdatefilter)
        .version("beta")
        .get((error,response: any,rawResponse?: any) => { ... }

我收到了消息并可以显示它们,但是我注意到某些消息中包含图像,这些图像也托管在团队聊天中,这就是“ hostedContent”。在我收到的消息(JSON)中,有一个属性body,它有一个content,它包含消息主体以及到这些hostedContent图像的链接。看起来像这样:

content:'<div><div><img alt="Sticker image,I CAN FIX IT" src="https://graph.microsoft.com/beta/teams/59b9b7d4-fd66-43cb-ae2b-03b4705f819f/channels/19:c73e19f4bb1841c9830f233d0d745eab@thread.skype/messages/1584028726132/hostedContents/aWQ9eF8wLXdldS1kMi05YjNhYWUxNGViY2Y2Njg5NzcyMTdmNGY2OTQxNzA0Zix0eXBlPTEsdXJsPWh0dHBzOi8vZXUtYXBpLmFzbS5za3lwZS5jb20vdjEvb2JqZWN0cy8wLXdldS1kMi05YjNhYWUxNGViY2Y2Njg5NzcyMTdmNGY2OTQxNzA0Zi92aWV3cy9pbWdv/$value" style="width:376px; height:251px"></div>\n</div>'

当我在WebPart中以HTML形式显示内容时,将呈现该内容,但图像不会呈现,它们返回401未经授权的响应。我相信所需的授权令牌未发送。我不确定为什么会发生这种情况,因为当前用户登录并且应该有权访问该资源,但是我想这是行不通的,因为src属性不会发送要求带有请求的身份验证承载令牌。

因此,要获取图像,我发现有一个API调用获取图像: https://docs.microsoft.com/en-us/graph/api/chatmessagehostedcontent-get?view=graph-rest-beta&tabs=http 好吧,基本上是我需要调用src属性的URL值,然后可以将接收到的图像转换为BLOB并使用它。

我的想法是使用graphClient进行API调用(如上例所示),将响应图像转换为BLOB,然后通过替换现有的src属性显示img标签和BLOB网址。

好吧,这几乎是上下文:-)-问题是,我现在如何最好地解析此字符串(代表HTML)并替换所说的img src属性

解决方法

感谢Andreas的帮助,我得以实现一个解决方案。

这里是一个示例(不使用image标记,因为它具有替换源代码的更复杂的逻辑):

第一个创建时态div以使用out标签:

    let temporalDivElement = document.createElement("div");
    temporalDivElement.innerHTML = message.content;

然后,在此示例中,我搜索一个名为“ attachments”的标签,找到所有标签,对其进行迭代,然后将其替换为SPAN标签。

// Attachments
const attachmentTags: NodeListOf<HTMLImageElement> = temporalDivElement.querySelectorAll(`attachment`);
attachmentTags.forEach((attachmentTag) => {
  let attachmentRemovedLink = document.createElement("a");
  attachmentRemovedLink.innerText = "Attachment Replaced";
  attachmentRemovedLink.href = urlXy;
  attachmentTag.parentNode.replaceChild(attachmentRemovedLink,attachmentTag);
});

有什么好用的,而且我现在最初并没有,querySelectorAll不仅可以通过标签名称选择内容,还可以实现更复杂的场景。

例如,使用该选择器,我可以选择所有包含特定src属性值的图像标签:

const imgTags: NodeListOf<HTMLImageElement> = temporalDivElement.querySelectorAll(`img[src*="/messages/${message.id}/hostedContents/"]`);