简体   繁体   中英

Set script tag from API call in header of index.html

I'm trying to implement dynatrace in my react app, and this works fine if I just add the required script tag manually in my index.html header.

However I want to make use of dynatraces api which returns the whole script tag element (so I can use for different environments).

How can I add the script tag to my index.html after calling the api? Creating a script element from code won't work because the response of the api call is a script tag itself (which is returned as string).

I tried creating a div element and adding the script as innerHtml, then append it to the document. But scripts don't get executed in innerHtml text.

const wrapperDiv = document.createElement("div");
wrapperDiv.innerHTML = "<script>alert('simple test')</script>";
document.head.appendChild(wrapperDiv.firstElementChild);

Can this be done?

I found a roundabout way of doing this:

const wrapperDiv = document.createElement("div");
const scriptElement = document.createElement("script");
wrapperDiv.innerHTML = "<script src=... type=...></script>";
for(let i = 0; i < wrapperDiv.firstElementChild.attributes.length; i++){
    const attr = wrapperDiv.firstElementChild.attributes[i];
    scriptElement.setAttribute(attr.name, attr.value);
}
document.head.appendChild(scriptElement);

in this example of the script i'm only using a src but this can be done with the value as well. If there is any better way for doing this pls let me know

This can be achieved without use of eval() :

const source = "alert('simple test')";
const wrapperScript = document.createElement("script");
wrapperScript.src = URL.createObjectURL(new Blob([source], { type: 'text/javascript' }));
document.head.appendChild(wrapperScript);

In the code above you basically create Blob, containing your script, in order to create Object URL (representation of File or Blob object in browser memory). This solution is based on idea that dynamically added <script> is evaluated by browser in case it has src property.

Update:

Since endpoint returns you <script> tag with some useful attributes, the best solution would be to clone attributes (including src ) - your current approach is pretty good.

I found a roundabout way of doing this:

const wrapperDiv = document.createElement("div");

const scriptElement = document.createElement("script");
wrapperDiv.innerHTML = "<script src=... type=...></script>";
for(let i = 0; i < wrapperDiv.firstElementChild.attributes.length; i++){
    const attr = wrapperDiv.firstElementChild.attributes[i];
    scriptElement.setAttribute(attr.name, attr.value);
}
document.head.appendChild(scriptElement);

in this example of the script i'm only using a src but this can be done with the value as well

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