Как я могу получить содержимое файла, указанного как 'src' тега <script>? - PullRequest
62 голосов
/ 29 сентября 2008

Если у меня есть такой скрипт-тег:

<script
    id = "myscript"
    src = "http://www.example.com/script.js"
    type = "text/javascript">
</script>

Я хотел бы получить содержимое файла "script.js". Я думаю о чем-то вроде document.getElementById("myscript").text, но в этом случае это не работает.

Ответы [ 15 ]

10 голосов
/ 29 сентября 2008

Вы хотите получить содержимое файла http://www.example.com/script.js? Если это так, вы можете обратиться к методам AJAX для извлечения его содержимого, предполагая, что оно находится на том же сервере, что и сама страница.

Не могли бы вы уточнить, что вы пытаетесь достичь?

10 голосов
/ 01 марта 2016

Я знаю, что уже немного поздно, но некоторые браузеры поддерживают свойство тега LINK rel="import".

http://www.html5rocks.com/en/tutorials/webcomponents/imports/

<link rel="import" href="/path/to/imports/stuff.html">

В остальном, ajax по-прежнему является предпочтительным способом.

5 голосов
/ 29 сентября 2008

Я не думаю, что содержимое будет доступно через DOM. Вы можете получить значение атрибута src и использовать AJAX для запроса файла с сервера.

3 голосов
/ 23 января 2018

tl; dr теги сценария не подпадают под действие CORS и same-origin-policy , и поэтому javascript / DOM не может предоставлять доступ к текстовому содержимому ресурс загружен через тег <script>, иначе он сломается same-origin-policy.

длинная версия: Большинство других ответов (и принятый ответ) правильно указывают, что « правильный » способ получить текстовое содержимое файла javascript, вставленного с помощью <script>, загруженного на страницу, использует XMLHttpRequest для выполнения другого отдельного дополнительного запроса для ресурса, указанного в свойстве src scripts, что будет продемонстрировано в приведенном ниже коротком коде javascript. Однако я обнаружил, что другие ответы не касались смысла получения текстового содержимого файлов javascript, то есть разрешение доступа к содержимому файла, включенного с помощью <script src=[url]></script>, приведет к нарушению политик CORS, например. современные браузеры не допускают XHR ресурсов, которые не предоставляют заголовок Access-Control-Allow-Origin , поэтому браузеры не позволяют получать содержимое каким-либо иным способом, кроме тех, которые относятся к CORS.

С помощью следующего кода (как упомянуто в других вопросах «используйте XHR / AJAX») можно выполнить еще один запрос для всех не встроенных тегов сценария в документе.

function printScriptTextContent(script)
{
  var xhr = new XMLHttpRequest();
  xhr.open("GET",script.src)
  xhr.onreadystatechange = function () {
    if(xhr.readyState === XMLHttpRequest.DONE && xhr.status === 200) {
      console.log("the script text content is",xhr.responseText);
    }
  };
  xhr.send();
}
Array.prototype.slice.call(document.querySelectorAll("script[src]")).forEach(printScriptTextContent);

и поэтому я не буду повторять это, но вместо этого хотел бы добавить через этот ответ аспект того, почему

0 голосов
/ 27 февраля 2017

Да, Ajax - способ сделать это, как в принятом ответе. Если вы приступите к деталям, есть много подводных камней. Если вы используете jQuery.load(...), подразумевается неправильный тип контента (html вместо application / javascript), который может испортить ситуацию, добавив нежелательный <br> в ваш (scriptNode) .innerText и тому подобное. Затем, если вы используете jQuery.getScript(...), скачанный скрипт будет немедленно запущен, что может не соответствовать вашему желанию (может испортить порядок загрузки файлов, если у вас их несколько).

Я нашел, что лучше всего использовать jQuery.ajax с dataType: "text"

Я использовал эту технику Ajax в проекте с набором фреймов, где для набора фреймов и / или нескольких фреймов требуется один и тот же JavaScript, чтобы сервер не отправлял этот JavaScript несколько раз.

Вот код, проверенный и работающий:

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Frameset//EN" "http://www.w3.org/TR/html4/frameset.dtd">
<html>
    <head>
        <script id="scriptData">
            var scriptData = [
                { name: "foo"    , url: "path/to/foo"    },
                { name: "bar"    , url: "path/to/bar"    }
            ];
        </script>
        <script id="scriptLoader">
            var LOADER = {
                loadedCount: 0,
                toBeLoadedCount: 0,
                load_jQuery: function (){
                    var jqNode = document.createElement("script");
                    jqNode.setAttribute("src", "/path/to/jquery");
                    jqNode.setAttribute("onload", "LOADER.loadScripts();");
                    jqNode.setAttribute("id", "jquery");
                    document.head.appendChild(jqNode);
                },
                loadScripts: function (){
                    var scriptDataLookup = this.scriptDataLookup = {};
                    var scriptNodes = this.scriptNodes = {};
                    var scriptNodesArr = this.scriptNodesArr = [];
                    for (var j=0; j<scriptData.length; j++){
                        var theEntry = scriptData[j];
                        scriptDataLookup[theEntry.name] = theEntry;
                    }
                    //console.log(JSON.stringify(scriptDataLookup, null, 4));
                    for (var i=0; i<scriptData.length; i++){
                        var entry = scriptData[i];
                        var name = entry.name;
                        var theURL = entry.url;
                        this.toBeLoadedCount++;
                        var node = document.createElement("script");
                        node.setAttribute("id", name);
                        scriptNodes[name] = node;
                        scriptNodesArr.push(node);
                        jQuery.ajax({
                            method   : "GET",
                            url      : theURL,
                            dataType : "text"
                        }).done(this.makeHandler(name, node)).fail(this.makeFailHandler(name, node));
                    }
                },
                makeFailHandler: function(name, node){
                    var THIS = this;
                    return function(xhr, errorName, errorMessage){
                        console.log(name, "FAIL");
                        console.log(xhr);
                        console.log(errorName);
                        console.log(errorMessage);
                        debugger;
                    }
                },
                makeHandler: function(name, node){
                    var THIS = this;
                    return function (fileContents, status, xhr){
                        THIS.loadedCount++;
                        //console.log("loaded", name, "content length", fileContents.length, "status", status);
                        //console.log("loaded:", THIS.loadedCount, "/", THIS.toBeLoadedCount);
                        THIS.scriptDataLookup[name].fileContents = fileContents;
                        if (THIS.loadedCount >= THIS.toBeLoadedCount){
                            THIS.allScriptsLoaded();
                        }
                    }
                },
                allScriptsLoaded: function(){
                    for (var i=0; i<this.scriptNodesArr.length; i++){
                        var scriptNode = this.scriptNodesArr[i];
                        var name = scriptNode.id;
                        var data = this.scriptDataLookup[name];
                        var fileContents = data.fileContents;
                        var textNode = document.createTextNode(fileContents);
                        scriptNode.appendChild(textNode);
                        document.head.appendChild(scriptNode); // execution is here
                        //console.log(scriptNode);
                    }
                    // call code to make the frames here
                }
            };
        </script>
    </head>
    <frameset rows="200pixels,*" onload="LOADER.load_jQuery();">
        <frame src="about:blank"></frame>
        <frame src="about:blank"></frame>
    </frameset>
</html>

связанный вопрос

0 голосов
/ 08 февраля 2011

Я бы посоветовал ответить на этот вопрос с помощью свойства innerHTML элемента DOM. Конечно, если скрипт загрузил , вам не нужно делать вызов Ajax для его получения.

Так что Сугендран должен быть верным (не уверен, почему его отвергли без объяснения причин).

var scriptContent = document.getElementById("myscript").innerHTML;

Свойство innerHTML элемента script должно предоставлять вам содержимое сценария в виде строки при условии, что элемент script:

  • встроенный скрипт или
  • , что скрипт загрузил (если используется атрибут src)

olle также дает ответ, но я думаю, что он «запутался» из-за того, что предложил сначала загрузить его через ajax, и я думаю, что он имел в виду «inline», а не между ними.

если вы находитесь между js, и вы можете получить к нему доступ через innerHTML.


По поводу полезности этой техники:

Я пытался использовать эту технику для регистрации ошибок на стороне клиента (исключений javascript) после получения «неопределенных переменных», которые не содержатся в моих собственных сценариях (таких как плохо внедренные сценарии с панелей инструментов или расширений) - так что я не думай, что это такая выходная идея.

0 голосов
/ 30 сентября 2008

Вы хотите использовать свойство innerHTML, чтобы получить содержимое тега script:

document.getElementById("myscript").innerHTML

Но, как сказал @olle в другом ответе, вы, вероятно, захотите прочесть: http://ejohn.org/blog/degrading-script-tags/

0 голосов
/ 29 сентября 2008

Надеюсь, вы уже используете некоторые библиотеки JavaScript ...

Как насчет получения значения атрибута src, URL-адреса, а затем с помощью инструментов Ajax вашей библиотеки отправьте запрос на этот URL-адрес и сохраните результат, где бы вы этого ни хотели?

Конкретные детали могут отличаться в зависимости от используемой вами библиотеки.

0 голосов
/ 29 сентября 2008

При использовании DOM-привязки в стиле 2008 было бы лучше:

document.getElementById('myscript').getAttribute("src");
document.getElementById('myscript').getAttribute("type");
0 голосов
/ 29 сентября 2008

В комментарии к моему предыдущему ответу:

Я хочу сохранить содержимое скрипта, чтобы я мог его кэшировать и использовать его напрямую через некоторое время без необходимости извлекать его с внешнего веб-сервера (не на том же сервере, что и страница)

В этом случае вам лучше использовать серверный скрипт для извлечения и кэширования файла скрипта. В зависимости от настроек вашего сервера вы можете просто wget файл (периодически через cron, если вы ожидаете, что он изменится) или сделать что-то подобное с небольшим скриптом на выбранном вами языке.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...