Боди скрипт что это
Руководство по JavaScript, часть 1: первая программа, особенности языка, стандарты
Недавно мы провели опрос, посвящённый целесообразности перевода этого руководства по JavaScript. Как оказалось, около 90% проголосовавших отнеслись к данной идее положительно. Поэтому сегодня публикуем первую часть перевода.
Это руководство, по замыслу автора, рассчитано на тех, кто уже немного знаком JavaScript и хочет привести свои знания в порядок а также узнать о языке что-то новое. Мы решили немного расширить аудиторию этого материала, включить в неё тех, кто совершенно ничего не знает о JS, и начать его с написания нескольких вариантов «Hello, world!».
Hello, world!
Программа, которую по традиции называют «Hello, world!», очень проста. Она выводит куда-либо фразу «Hello, world!», или другую подобную, средствами некоего языка.
JavaScript — это язык, программы на котором можно выполнять в разных средах. В нашем случае речь идёт о браузерах и о серверной платформе Node.js. Если до сих пор вы не написали ни строчки кода на JS и читаете этот текст в браузере, на настольном компьютере, это значит, что вы буквально в считанных секундах от своей первой JavaScript-программы.
Этот текст можно ввести с клавиатуры, можно скопировать и вставить его в консоль. Результат будет одним и тем же, но, если вы учитесь программировать, рекомендуется вводить тексты программ самостоятельно, а не копировать их.
Первая программа в консоли браузера — вывод сообщения в консоль
Ещё один вариант браузерного «Hello, world!» заключается в выводе окна с сообщением. Делается это так:
Вот результат выполнения этой программы.
Вывод сообщения в окне
Обратите внимание на то, что панель инструментов разработчика расположена теперь в нижней части экрана. Менять её расположение можно, воспользовавшись меню с тремя точками в её заголовке и выбирая соответствующую пиктограмму. Там же можно найти и кнопку для закрытия этой панели.
Инструменты разработчика, и, в том числе, консоль, имеются и в других браузерах. Консоль хороша тем, что она, когда вы пользуетесь браузером, всегда под рукой.
Почему скрипты в конце тега body
Я знаю, этот вопрос задавался много раз, но я не нашел ответа. Так почему же рекомендуется включать скрипты в конце тега body для лучшего рендеринга?
Итак, если мы получили:
и если скрипт во главе:
CRP будет таким же:
этот вопрос касается только скриптов» sync » (без атрибута async / defer).
4 ответов
скрипты, исторически, заблокировали дополнительные ресурсы от загрузки быстрее. Разместив их внизу, ваш стиль, контент и медиа могут загружаться быстрее, давая восприятие повышение производительности.
дальнейшее значение: async и defer атрибуты.
на мой взгляд, это устаревшая практика. В последнее время предпочтение отдается JavaScript для разделения любого кода, который требует, чтобы DOM присутствовал в прослушивателе событий «DOMContentLoaded». Это не обязательно все логика; много кода можно инициализировать без доступа к полному DOM.
Это правда, что это вызывает небольшой момент, когда извлекается только файл скрипта, и ничего больше (например, изображения). Это небольшое окно можно пропустить мимо добавление async атрибут, но даже без него я рекомендую поместить теги скриптов в голову, чтобы браузер знал, как можно скорее загрузить их, а не сохранять их (и любые будущие запросы, инициированные JS) для последнего.
изображения, помещенные под тегом сценария, будут ждать загрузки до загрузки сценария JS. Разместив тег скрипта внизу, вы сначала загружаете изображения, создавая видимость более быстрой загрузки страницы.
Я думаю, это зависит от вашего сайта или приложения. Некоторые веб-приложения основаны на JavaScript. Тогда не имеет смысла включать его в нижней части страницы, но загрузить его немедленно. Если JavaScript просто добавляет некоторые не очень важные функции на некоторую страницу на основе контента, то лучше загрузить его в конце. Время загрузки будет практически одинаковым, но важные детали пользователь увидит раньше (до завершения загрузки страницы).
речь идет не о загрузке всего сайта быстрее, но дает пользователь впечатление от какой-то загрузки сайта быстрее.
например: Вот почему веб-сайты на основе Ajax могут дать гораздо более быстрое впечатление. Интерфейс всегда один. Просто некоторые части контента изменятся.
У меня в админке ссылки на скрипты заданы в разделе head в главном шаблоне сайта, а в примере ссылки на скрипты заданы в body причем сразу после div тега.
ссылки на js как раз нужно перед закрытием в body, что бы не мешало рендеру документа, считается хорошей практикой которая ускоряет отрисовку страницы
Неужто в 2014 году есть такая проблема.
в любом году есть и будет почитайте рекомендации гугла по оптимизацию фронтенда на страничках https://developers.google.com/speed/pagespeed/?hl=ru + можно протестировать свой сайт
в хроме то работает, а вот в других не факт, что все тип-топ будет, выносить за ничего нельзя по спецификации, а кто-как это в движках реализует дело десятое, ну и толку вплане скорости тут всеравно нет, поэтому лучше так не делать.
js блокирует рендер страницы, как-раз в head стараются не пихать.
+ есть хаки по-типу async, специально для этого разработанные.
Так что давай, если ты не в теме топика, то и не будешь советовать, ок?
Это для ускорения отрисовки? Мне всё-таки интересно, где сегодня такое действительно необходимо?
Необходимо на медленных соединениях. Если скрипты стоят в начале документа, то браузер ничего не нарисует, пока их полностью не скачает (даже если скрипты не выполняются сразу).
Введение в HTML импорты
Template, Shadow DOM, и Custom Elements позволяют вам строить UI компоненты проще и быстрее. Однако, это не самый эффективный способ загрузки ресурсов HTML, CSS и JavaScript по отдельности.
Для загрузки библиотек типа jQuery UI или Bootstrap требуются отдельные тэги для JavaScript, CSS, и Web шрифтов. Все становится проще при использовании Web Components с несколькими зависимостями.
HTML импорты позволяют загружать ресурсы как совокупность нескольких файлов этого типа.
Предлагаю вам ознакомиться с видео по данной теме.
Использование HTML импортов
Вы можете загружать любые ресурсы, включая скрипты, таблицы стилей и шрифты:
component.html
Порядок исполнения
Браузеры обрабатывают контент по порядку. Это означает, что script в начале HTML будет загружен раньше, чем то же самое, но в конце. Учтите, что некоторые браузеры ожидают завершения исполнения скрипта перед тем, как загружать следующие элементы.
Во избежание блокировки тэгом script оставшегося HTML можно использовать атрибуты async / defer (также можно переместить все скрипты в конец страницы). defer указывает на то, что код можно запустить лишь после загрузки HTML. async позволяет браузеру выполнять эти два действия параллельно.
Итак, как же работают импорты?
За рамками происходящего
На самом деле, HTML импорты не могут перенести полностью файл с другого источника. К примеру, вы не можете импортировать в http://example.com/ страницу http://webcomponents.org/.
Чтобы избежать этого ограничения, используйте CORS (Cross Origin Resource Sharing). Чтобы узнать больше об этой технологии, прочтите эту статью.
Объекты window и document в импортируемых файлах
Ранее я упоминал то, что импортируемые JavaScript будут запущены на странице. К сожалению, такое нельзя сказать об импортируемых HTML файлах. Чтобы такое происходило и с ними, надо дописать немножко скриптов.
Остерегайтесь того, что объект document в импортируемом файле будет ссылаться на страницу оригинала.
Внесем небольшие изменения в наши файлы.
index.html
Вопросы производительности
Один из плюсов использования импортов — возможность самостоятельно распределить нагрузку страницы и порядок обработки импортируемых объектов. Но это еще и означает, что HTML код увеличится. Вообще, есть несколько пунктов для сравнения:
Зависимости
Что делать, если несколько вставляемых документов ссылаются на одну и ту же библиотеку? Например:
Вы загружаете jQuery в обоих документах, из-за чего при импорте этих документов библиотека в конечном документе будет исполнена дважды.
index.html
Данная проблема крайне легко решается в импортах.
К счастью, нам на помощь идет инструмент под названием «Vulcanize».
Объединение сетевых запросов
Для объединения файлов index.html используем следующий код:
Прочитать больше о данном инструменте можно здесь.
Сочетание импортов с Template, Shadow DOM и Custom Elements
Поддерживаемые браузеры
HTML импорты поддерживаются браузерами Chrome и Opera. Firefox на данный момент отложил добавление данной фичи, так как «у них есть более приоритетные задачи».
Прячем, обфусцируем и криптуем клиентскую часть веб-приложений
Обфусцированный скрипт
Теория
Работа JJEncode
Базовое шифрование HTML/CSS
Что делать, если нам нужно зашифровать HTML или CSS код? Все просто: зашифровать на JavaScript, а после расшифровки вставить как HTML код.
Пример вставки (без шифровки/крипта/обфускации):
Точно так же мы поступим и с CSS-стилями:
Теперь постараемся абстрагироваться от HTML и CSS и поговорить только о самой сути — сначала скрытии, а затем и криптовке JavaScript.
Прежде, чем кто-либо захочет посмотреть и расшифровать наш код, он постарается его найти. Ниже ты найдешь несколько действенных методов сокрытия кода от глаз любопытных пользователей.
Прячем слово «][akep» в теле документа
Замена атрибутов тега
А теперь просто создадим папку «text», в которую положим наш скрипт («script.js») под именем «javascript» и поменяем атрибуты местами. Это будет выглядеть так:
Для лучшего эффекта сразу отвлечем внимание пользователя на путь. Например, так:
Проверено на личном опыте: работает отлично! Таким способом я сам накручивал партнерку по кликам, так как пришлось использовать накрутчик на JavaScript. Администрация партнерки его так и не увидела :).
JavaScript-обработчики
Данный способ также не является универсальным средством для сокрытия JS-кода, но все же я расскажу о нем. Главная идея состоит в том, чтобы прятать код внутрь обработчиков событий onLoad, onClick и т.д. То есть примерно в следующие конструкции:
Например, для тегов body и frameset есть обработчик onLoad, который запустит в нем прописанный код после загрузки страницы/фрейма.
Отмечу, что не для всех объектов обработчики одинаковы.
Cookie, Referrer и адрес
JavaScript можно также спрятать и в такие нестандартные места, как cookie (document.cookie), реферрер (document.referrer) и адрес страницы (location.href). В данном случае код будет храниться как обычный текст, а выполняться с помощью функции eval(), которая берет в качестве аргумента текст и выполняет его как JavaScript-код.
В качестве примера примем такое допущение, что у нас уже установлены кукисы следующего вида:
Теперь выполним этот алерт следующим образом:
Здесь мы берем текст всех cookie-записей для нашего хоста и делим его на части в местах, где стоит «||». Затем берем второй элемент ([1]) и запускаем его через eval().
Данный способ не так уж и плох, так как код, который мы хотим исполнить, не виден на самой странице, а также потому, что мы можем заставить код удалить самого себя! Пример реализации:
Аналогичным образом можно использовать и другие строки, доступные через JavaScript, например, location.href и document.referrer.
Сокрытие кода на Ajax
Нуллбайт атакует Оперу
Этот метод прост и достаточно эффективен, но, к сожалению, он рассчитан только на браузер Opera. Суть метода в том, чтобы перед скрываемым кодом поставить так называемый нуллбайт (нуллбайт или nullbyte — это символ с ASCII кодом «0»). Зачем? Затем, что Opera просто-напросто не показывает код во встроенном просмотрщике после данного символа. Пример:
В данном примере сначала идет нормальный код, который нам скрывать не требуется. Потом с помощью PHP мы вставляем нуллбайт, а после него идет скрываемый код.
Прячемся в HTML-коде и комментариях
Код можно легко спрятать в HTML, затем обработать его и выполнить. Например, вот так:
В данном случае мы спрятали код в атрибутах тега img, после чего обработали код всей страницы, собирая разбросанные кусочки. Таким же способом можно скрывать текст в HTML/JavaScript комментариях:
Отдельно стоит отметить, что очень эффективно можно прятать код внутри популярных фреймворков — например, jQuery, mooTools и подобных. Эти файлы не являются подозрительными, а исследование их займет много времени (хотя всегда существует возможность автоматического сравнения оригинала и измененного файла).
Теперь же, думаю, можно поговорить о том, что, в конце концов, видит эксперт безопасности, и о том, что исследуют антивирусы. Ниже читай о наиболее популярных методах криптовки и обфускации JS-кода.
Субституция стандартных функций/методов JavaScript
Данный метод ориентирован на то, чтобы вместо стандартных функций или методов JavaScript подставить свои переменные:
Флуд комментариями и кодом
Данный способ рассчитан на то, чтобы вставить в обфусцируемый код флуд, то есть что-то, что не несет смысловой нагрузки для кода скрипта. Флудить можно как код, так и комментарии:
В данном случае мы — во-первых, использовали внутреннюю переменную «cookie» объекта «document», как элемент массива. Во-вторых, мы перевели ее имя в шестнадцатеричный формат. Если бы мы использовали переменную «cookie» через точку, то есть как document.cookie, то мы бы не смогли перевести обращение к ней в шестнадцатеричный формат, так как это относится только к строкам (в массиве ключ является строкой), а в document.cookie строк нет.
PHP-функция перевода в шестнадцатеричный формат:
Трюк с несуществующими функциями
Как мы уже знаем из прочитанного выше, в JavaScript можно вызывать методы, как элементы обьекта: document.getElementById и document[‘getElementById’]. Оба варианта фактически одинаковы, различие есть только в записи — во втором варианте мы используем строку.
Как-то вечером я придумал очень интересный способ получения подобных строк. Например, нам нужно зашифровать вышеупомянутый «getElementById». Отвлечемся на короткое объяснение данного способа с помощью такого примера:
Этот скрипт не будет работать, так как функции b, c и d не были ранее объявлены. Теперь попробуем сделать так, чтобы этот код заработал, для этого будем использовать «песочницу» конструкции try<>catch()<>:
После запуска мы увидим ошибку, а это значит, что, хоть код и не является рабочим, он не остановил выполнение оставшейся корректной части.
А вот теперь мы зададимся вопросом, как такая схема может быть связана с шифрованием строки «getElementById»? А вот так:
После выполнения этого кода у нас получится строка «getElementById», содержащаяся в переменной «x».
В чем соль этого метода? В том, что эвристический анализ антивирусов при нахождении функций будет ругаться на то, что они не существуют. Тем самым мы обфусцируем код не на уровне шифровки строк разными способами, а на уровне получения данных строк от самого JavaScript.
Числа с помощью оператора «
» (тильда) является битовым отрицанием и используется вот так: «alert(
13);». Этот код выведет нам «-14». Работает данный оператор по принципу «-(число+1)».
Представим, что мы хотим присвоить переменной «a» какое-нибудь число, причем нигде это число не писать: «a =
[]»;
Данный код присвоит переменной «a» число «-1». Почему? Потому что массив представляет собой нейтральный элемент с числовым значением «0», следовательно,
Буквы и строки без строковых данных
Иногда требуется получить букву/символ или какой-то текст без его явного написания. Сделать это позволяет одна особенность JavaScript. В этом языке существуют различные внутрисистемные сообщения, которые можно преобразовать в текст, а затем этот текст обработать.
Например, представим, что нам нужно получить текст «code». Эта строка содержится в именах таких методов, как charCodeAt(), fromCharCode() и других. Получить текст можно следующим образом:
В данном примере переменная «a» будет содержать текст «code». Разберем подробнее. Попробуй исполнить вот такой код: «alert(alert+»);». Ты увидишь что-то вроде «function alert() < [native code] >». Тем самым, использовав всего-навсего два раза функцию alert(), мы получили совершенно другие символы.
Теперь постараемся понять, как это все работает. Представим, что у каждого объекта, функции и всего остального в JavaScript есть некое «описание». Чтобы получить к нему доступ, нужно явно изменить тип данного объекта или функции на строковой, присоединив, например, пустую строку (+»»).
Шифровка строк
Для шифровки/расшифровки строк в JavaScript существуют несколько полезных функций. Разберем некоторые из них:
Также есть два метода объекта String, которые работают с преобразованием символа в ASCII-код и наоборот:
Преобразование объектов/переменных
Имена объектов и переменных можно также преобразовать в строку (например, чтобы потом эту строку зашифровать). Преобразование происходит по тому же принципу, что и преобразование имен методов, то есть с помощью перехода из формы «.метод» в форму «[метод]». Для корректного преобразования нужно найти еще более высокий в иерархии объектов элемент, который бы имел внутри себя слово «document». Имя ему this. Согласно стандартам JavaScript, this не является объектом, а является оператором, возвращающим ссылку на объект. В результате теперь мы можем безболезненно использовать getElementById таким образом: «this[«document»][«getElementById»]».
Привязка кода
Избегание подозрительных функций
Советую также избегать явное использование функций eval(), document.write() и других. При поиске настоящего кода люди часто используют метод подстановки alert() вместо данных функций, так как после этого код можно сразу прочитать таким, каким мы его начинали шифровать, следовательно, весь смысл обфускации пропадает. Как же выполнить код, не используя фунцкию eval()?
Вспомним про то, что во главе всего стоит оператор this. С помощью него функцию eval() можно превратить вот в такой код:
После такого преобразования мы спокойно сможем использовать «a()» вместо «eval()».
Изменение на нечитаемые строки
Шифрование кода
Способов шифровки текста существует неограниченное количество, хотя все они основаны на использовании каких-либо текстовых/числовых функций. Часто работает конструкция: eval() + функция_расшифровки() + шифрованная_строка. Попробую без лишней воды показать один из таких способов.
Допустим, нам нужно зашифровать строку «alert(1);». Мне пришло в голову брать по два символа из нее, переводить их в числа (ASCII код), считывать их и рядом ставить первый символ в чистой (без перевода) форме. Только стоит учесть, что, разделяя код на такие двухбуквенные части, мы получим код примерно в 2-2,5 раза больше оригинала, а также нельзя забывать, что такие блоки лучше как-то разделять (как элемент массива или через разделитель). За разделитель возьмем знак «%», так как он делает шифрованную строку похожей на URL-строку. Напишем простой PHP-скрипт:
Вот что у нас получилось: « %a205%e215%t156%190%;59 ».
А теперь напишем дешифровщик этого кода на JavaScript:
Вызов кода в таком случае будет выглядеть так: «eval(d(‘%a205%e215%t156%190%;59’));».
Теперь остается только немного обфусцировать весь этот скрипт. Мы не будем использовать все описанные методы, а затронем лишь некоторые из них:
Напоследок
Ну что ж, подведем итоги. При комбинации всех этих способов можно быть на 100% уверенным, что простой или даже средний пользователь не сможет прочитать или скопировать к себе твой код. Но так как специалисты по компьютерной безопасности прекрасно знают о большинстве данных трюков, а также потому что я выкладываю эту информацию на всеобщее обозрение, могу предположить, что данные методы станут более популярными и известными. Я надеюсь, что ты сможешь использовать представленную информацию в благих целях.
Делаем скрипт читаемым
Журнал Хакер, Сентябрь (09) 152
|qbz| (lopuxin.iv@yandex.ru, http://essenzo.net).