我如何 replace/update 字符串中的特定 HTML 标签
How can I replace/update specific HTML tag inside string
我有一个 SPFx 现代 Web 部件,使用 React 和 TypeScript。我正在使用 Microsoft Graph API 从 Teams 频道获取消息:
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 时,内容得到呈现但图像没有呈现,它们 return 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,然后通过替换现有的 [= img
标签的 17=] 属性与 BLOB-url.
好吧,这就是上下文 :-) - 所以问题是,我现在如何最好地解析这个字符串(代表 HTML)并替换所说的 img
src
属性?
感谢 Andreas 的提示,我得以实施解决方案。
这里有一个例子(没有使用图像标签,因为它有更复杂的逻辑来替换源代码):
1st 创建时间 div 以使用标签:
let temporalDivElement = document.createElement("div");
temporalDivElement.innerHTML = message.content;
然后,在这个例子中,我搜索一个名为“附件”的标签,找到所有标签,遍历它们并将它们替换为 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
你不仅可以 select 通过标签名称来实现,还可以实现更复杂的场景。
例如,使用此 select 或者我可以 select 所有包含特定 src
属性值的图像标签:
const imgTags: NodeListOf<HTMLImageElement> = temporalDivElement.querySelectorAll(`img[src*="/messages/${message.id}/hostedContents/"]`);
我有一个 SPFx 现代 Web 部件,使用 React 和 TypeScript。我正在使用 Microsoft Graph API 从 Teams 频道获取消息:
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 时,内容得到呈现但图像没有呈现,它们 return 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,然后通过替换现有的 [= img
标签的 17=] 属性与 BLOB-url.
好吧,这就是上下文 :-) - 所以问题是,我现在如何最好地解析这个字符串(代表 HTML)并替换所说的 img
src
属性?
感谢 Andreas 的提示,我得以实施解决方案。
这里有一个例子(没有使用图像标签,因为它有更复杂的逻辑来替换源代码):
1st 创建时间 div 以使用标签:
let temporalDivElement = document.createElement("div");
temporalDivElement.innerHTML = message.content;
然后,在这个例子中,我搜索一个名为“附件”的标签,找到所有标签,遍历它们并将它们替换为 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
你不仅可以 select 通过标签名称来实现,还可以实现更复杂的场景。
例如,使用此 select 或者我可以 select 所有包含特定 src
属性值的图像标签:
const imgTags: NodeListOf<HTMLImageElement> = temporalDivElement.querySelectorAll(`img[src*="/messages/${message.id}/hostedContents/"]`);