Сценарий диаграмм электронной почты Sparkline

Для тех, кто все еще пытается это сделать, нет, вы не можете вставлять скрипт с помощью innerHTML, но можно загрузить строку в тег скрипта с помощью Blob и URL.createObjectURL.

Я создал пример, который позволяет запускать строку как скрипт и получать «экспорт» скрипта, возвращенного с помощью обещания:

function loadScript(scriptContent, moduleId) {
    // create the script tag
    var scriptElement = document.createElement('SCRIPT');

    // create a promise which will resolve to the script's 'exports'
    // (i.e., the value returned by the script)
    var promise = new Promise(function(resolve) {
        scriptElement.onload = function() {
            var exports = window["__loadScript_exports_" + moduleId];
            delete window["__loadScript_exports_" + moduleId];
            resolve(exports);
        }
    });

    // wrap the script contents to expose exports through a special property
    // the promise will access the exports this way
    var wrappedScriptContent =
        "(function() { window['__loadScript_exports_" + moduleId + "'] = " + 
        scriptContent + "})()";

    // create a blob from the wrapped script content
    var scriptBlob = new Blob([wrappedScriptContent], {type: 'text/javascript'});

    // set the id attribute
    scriptElement.id = "__loadScript_module_" + moduleId;

    // set the src attribute to the blob's object url 
    // (this is the part that makes it work)
    scriptElement.src = URL.createObjectURL(scriptBlob);

    // append the script element
    document.body.appendChild(scriptElement);

    // return the promise, which will resolve to the script's exports
    return promise;
}

...

function doTheThing() {
    // no evals
    loadScript('5 + 5').then(function(exports) {
         // should log 10
        console.log(exports)
    });
}

Я упростил это из своего фактическая реализация, поэтому нет обещаний о том, что в нем нет ошибок. Но принцип работает.

Если вам не нужно возвращать какое-либо значение после запуска скрипта, это еще проще; просто оставьте Promise и onload бит. Вам даже не нужно обернуть скрипт или создать глобальное свойство window.__load_script_exports_.

0
задан Dnib 13 July 2018 в 18:28
поделиться