2015-06-15 3 views
3

У меня есть удаленный скрипт, на который ссылается в HEAD моей страницы HTML. Этот первый скрипт загружает и вставляет другой скрипт, добавляя его в DOM. Оба сценария существуют в другом домене, чем страница, на которой они встроены.Как сделать вставленную загрузку javascript перед DOMContentLoaded?

содержимое первого сценария выглядит следующим образом:

(function(){ 
    var siteIdentifier = ... 
    var scriptTag = document.createElement('script'); 
    scriptTag.type = 'text/javascript'; 
    scriptTag.src = '//blah.com/foo/' + siteIdentifier + '/second_script.js'; 
    scriptTag.async = true; 
    document.getElementsByTagName('head')[0].appendChild(scriptTag); 
})(); 

Когда я пытаюсь это в Chrome (версия 43.0.2357.81, 64-разрядная версия), я вижу, что первый сценарий загружается очень рано временной шкале. Но второй скрипт никогда не загружается сразу после события DOMContentLoaded.

На следующем скриншоте показана временная шкала загрузки/выполнения для двух сценариев. Первый скрипт - это верхний элемент, а второй - нижний. Игнорируйте элемент в середине, который является другим артефактом, который я не мог отфильтровать из временной шкалы для снимка экрана. Вертикальная синяя линия - это событие DOMContentLoaded.

enter image description here

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

Update:

Я создал пример, чтобы показать проблему с помощью RawGit и GIST:

https://rawgit.com/javidjamae/43f81b4fb654e133cfe9/raw/87abe3a5351d120bdd316503d221f02ad6d3f699/index.html

Открыть инструменты разработчика Chrome и смотрите на вкладке сети как страница загружается. Вы можете использовать ползунки на временной шкале, чтобы узко на определенный период времени и посмотреть, какие сценарии были загружены, когда. Возможно, вам придется обновиться несколько раз, чтобы убедиться, что shim.js был загружен задолго до события DOMContentLoaded, но вы заметите, что second.js никогда не загружается до DOMContentLoaded независимо от того, загружается ли shim.js и завершается выполнение.

Примечание: Я не мог использовать JSFiddle, потому что он не загружает все, что вы определяете, включая внешние скрипты, до тех пор, пока DOMContentLoaded.

Update 2:

Для некоторого фона: Мы строим 3-й продукт партии, который внедренный на сотни различных сайтов. Первый скрипт фактически является прокладкой, которая извлекает некоторую идентифицирующую информацию, а затем вызывает второй скрипт, используя идентифицирующую информацию как часть URL-адреса. Мы переводим всех, чтобы использовать второй скрипт напрямую, но пока все наши клиенты не перейдут к использованию второго скрипта напрямую, нам нужна прокладка, чтобы эффективно маршрутизировать их автоматически. И первый, и второй скрипты являются динамически генерируемыми (то есть серверными) сценариями, которые находятся за CDN.

+1

Я полагаю, это потому, что вы не можете использовать 'document.getElementsByTagName' до тех пор, пока' document' не будет полностью доступен. – Blazemonger

+0

Единственный способ действительно гарантировать, что это вместо 'document.write()' тег, но в целом это плохая идея, поскольку он заставляет браузер ждать 'document.write()', чтобы разрешить, что означает браузер должен дождаться загрузки сценария * и *. Alt alt должен помещать тег скрипта непосредственно на странице (как фактический тег скрипта, поэтому он блокируется) –

+0

В этом случае, я думаю, 'document.write' может быть правильным решением. – Blazemonger

ответ

0

Как указано в комментариях, учитывая, что ваш первый скрипт опирается на DOM для загрузки второго скрипта, я не думаю, что вы найдете чистое решение JS.

Предлагаю написать сценарий на стороне сервера (например, jsp), который будет использоваться как файл js. У вас может быть расширение .js, чтобы сказать jsp.

В коде сервера вы можете получить второй скрипт, проходящий в соответствующих параметрах. <script src="/webapp/jsp_file.js"> Затем в файле jsp используйте tag libraries для импорта второго js.

Это имеет уродливый недостаток вашего сервера, который становится реальным клиентом для второго js - может привести к проблемам с производительностью. & также может сломать второй файл js, если он полагается на заголовки запросов/ip-фильтрацию.

+0

Спасибо, но я думаю, вы пропустили это. Мне нужно захватить данные из DOM, прежде чем я смогу сформировать URL для второго скрипта. Смотрите мой комментарий к JoshJ в исходном посте. Оба сценария на самом деле являются сценариями на стороне сервера. –

Смежные вопросы