问题描述
我有一个使用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/"]`);