简体   繁体   中英

How can I replace/update specific HTML tag inside string

I have a SPFx modern webpart, using React and TypeScript. I am consuming the Microsoft Graph API to fetch messages from a 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) => { ... }

I receive the messages and can display them, but I noticed that some messages have images in them, which are also hosted inside the Team Chats, this is known as "hostedContent". Inside the messages I receive (JSON) there is a property body , which has a child content that contains the message body and also the links to those hostedContent images. This looks like this:

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>'

When I display this content as HTML inside my WebPart, the content gets rendered but the images do not, they return a 401 unauthorized response. I believe the needed authorization token is not sent. I'm not exactly sure why this happens, as the current user is logged in and should have the right to access the resource but I guess, that it doesn't work this way as the src attribute does not send the required authentication bearer token with the request.

So, to get the images, I found out that there is an API call to get the images: https://docs.microsoft.com/en-us/graph/api/chatmessagehostedcontent-get?view=graph-rest-beta&tabs=http Well, it's basically the URL value from the src attribute that I need to call and then I could convert the received image into a BLOB and use it.

My idea was to make the API call using the graphClient (as seen in the example above), convert the response image to a BLOB and then display it by replacing the existing src attribute of the img tag with the BLOB-url.

Well, that's pretty much context :-) - so the question is, how can I now best parse this string (representing HTML) and replace said img src attribute?

Thanks to the tip of Andreas I was able to implement a solution.

Here is an example (not using the image tag, as it has a more complex logic in it to replace the source):

1st create a temporal div to work with out tags:

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

Then, in this example, I search for a tag called "attachments", I find all, iterate over them and replace them with a SPAN tag.

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

What's cool, and I didn't now initially, with querySelectorAll you can not only select stuff by a tag name, but you can also implement more complex scenarios.

For example with this selector I can select all image tags that contain a specific src attribute value:

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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