§5.4. Браузерные скрипты

На заре интернета веб-страницы выглядели примерно так:

Всё изменилось, когда в 1995 году стажёр одной известной браузерной компании разработал язык программирования JavaScript (JS). Это язык, работающий внутри браузера и позволяющий программистам писать и встраивать в веб-страницы скрипты — особый код, который может выполняться на компьютерах пользователей.

От шутки к приложениям

Первые версии JS позволяли лишь изменять содержимое и оформление страницы, делать математические вычисления, а также обрабатывать пользовательский ввод. Кажется, что это не так много, но на самом деле даже такого набора достаточно, чтобы делать полезные или интересные вещи. Например, встроить в страницу калькулятор:

+ =

До появления JS такой калькулятор можно было сделать только используя HTTP-запросы и вычисления на сервере: вы бы нажали кнопку, браузер бы отправил данные как GET- или POST-параметры, сервер бы посчитал данные и отправил бы вам новую страницу, в которой вам был бы дан ответ. И всё ради того, чтобы сложить два числа!

Этот пример отлично показывает, что не всё уместно выполнять на сервере — несложные действия можно поручить клиентскому браузеру, ведь это, как минимум, быстрее и удобнее для пользователя. Кроме того, некоторые действия в принципе невозможно осуществить на сервере:

Со временем в JavaScript появлялись новые возможности. Внутри браузера стало возможным делать разные удивительные вещи: запускать нейросети, рисовать 3D-графику в реальном времени и даже взаимодействовать с музыкальными инструментами. Современные сайты всё меньше выглядят как гипертекстовые документы и всё больше похожи на настоящие приложения, нередко превосходя их в удобстве и возможностях.

Microsoft Outlook 97. Оригинал: пользователь Wikimedia Commons Piotrhnh, CC BY-SA 4.0

Под микроскопом

Давайте рассмотрим устройство скриптов на практике. Все необходимые инструменты для этого у нас уже есть. Запустите веб-инспектор, нажав F12 или выбрав соответствующий пункт меню вашего браузера. В инспекторе выберите вкладку Console.

Браузерная консоль чем-то похожа на знакомый вам терминал. Отличие в том, что здесь можно выполнять код на JS, а не системные команды, и получать результаты его выполнения.

Можно заставить браузер, например, сделать красиво, но уже самостоятельно. Для этого наберите в консоли следующий код:

document.body.style.background = "#ffaaff"

Произошло вот что: для тега <body> вы указали новое значение атрибута style — CSS-правило background, после чего браузер перерисовал страницу с учётом этих изменений. Теперь попробуйте вернуть всё как было. Для этого можно выполнить предыдущий код, но вместо розового указать белый цвет в шестнадцатеричном формате (cм. §1.6). Если не получилось — не беда, просто перезагрузите страницу.

Хотите ещё?

  • Попробуйте поиграться с этими примерами:
    new Audio("hi.mp3").play()setInterval(()=>console.log(new Date()), 1000)document.body.innerHTML='<img src="pic/rooster.png">'

В программировании часто бывает так, что надо одним разом выполнить несколько действий. Для этого действия группируют в процедуры — части кода с именем, по которому их можно многократно вызывать. Попробуйте объявить процедуру с именем hi в консоли — для этого просто скопируйте и вставьте этот фрагмент кода в консоль:

function hi() {
  alert("Привет!")
  alert("Как дела?")
}

Заметьте, что после объявления процедуры ничего не произошло. Но ничего и не должно было произойти — процедуру мало объявить, её надо ещё и вызвать. Это тоже несложно — просто вспомните её имя и добавьте пару круглых скобок:

hi()

Процедуры особенно полезны, когда вам нужно обрабатывать пользовательский ввод — скажем, нажатие на кнопку. Давайте посмотрим, как это сделано в кнопке Сделать хорошо. Для этого переведите веб-инспектор в режим прицеливания, нажав на  в левом верхнем углу, а затем на саму кнопку. Веб-инспектор отобразит соответствующий ей элемент:

Видно, что у неё есть атрибут onclick со значением prettify(). Нетрудно догадаться, что этот атрибут указывает браузеру на процедуру, которую надо вызвать, когда кнопка будет нажата. Так и есть. Что же это за процедура? Можно узнать эмпирически, выполнив в консоли prettify(), но это не самый рациональный способ. Давайте лучше изучим исходный код. Для этого откройте вкладку Debugger (или Sources в Chrome), выберите текущую страницу (scripts.html) в панели слева, нажмите Ctrl-F и наберите в открывшейся панели поиска название искомой процедуры. Вы увидите вот это:

function prettify() {
  document.body.style.background = '#ffaaff'
  document.getElementById('knopka').textContent = 'Вернуть как было'
  document.getElementById('knopka').onclick = uglify
}
function uglify() {
  document.body.style.background = '#ffffff'
  document.getElementById('knopka').textContent = 'Сделать красиво'
  document.getElementById('knopka').onclick = prettify
}

Заметьте, что процедур на самом деле две, и что ничего сложного в них нет. Первая строка в каждой функции нам уже знакома по примерам чуть выше, а document.getElementById('knopka') — это способ обратиться к конкретной кнопке среди многих: во второй строке мы задаём ей новый текст, а в третьей — переопределяем её обработчик события.

Таким образом, нажимая на кнопку в первый раз, выполняется процедура prettify, которая меняет фон и делает так, чтобы отныне при нажатии на кнопку вызывалась процедура uglify. Процедура uglify в свою очередь делает всё то же, но наоборот. Получается замкнутый круг, благодаря которому в итоге кнопка то делает красиво, то возвращает всё как было.

Примечание

  • В современном браузере очень много событий. Можно следить не только за действиями мыши или клавиатуры, но и, например, за этапами загрузки страницы или статусом воспроизведения видео. К слову, атрибуты — не самый лучший способ задавать обработчики событий.

Безопасность

Разумеется, целый язык программирования в браузере — это серьёзная проблема с точки зрения безопасности, ведь формально кто угодно может получить доступ к вашему браузеру и делать в нём всё, что захочет. Эту проблему активно решают: браузеры научились спрашивать у пользователя разрешение, прежде чем что-то делать, а функций, которыми злоумышленники могут просто так воспользоваться, становится всё меньше и меньше, появляются целые политики безопасности.

Стоит отметить, что JS — это угроза не только для клиентов, но и для владельцев сайтов. Поскольку все скрипты выполняются непосредственно в браузере, у пользователей есть возможность влиять на их исполнение. Именно из-за этого все важные данные должны обрабатываться на сервере — в браузер стоит передавать только то, что точно можно показывать пользователю.

Выводы

  1. Браузерные скрипты — встроенные в веб-страницы программы, с помощью которых можно заставлять браузер делать практически что угодно. Их пишут на языке JavaScript.

  2. Скрипты всегда скачиваются и выполняются на стороне клиента. Их содержимое можно изучить с помощью веб-инспектора. В основном они состоят из процедур, которые можно вызывать.

  3. Скрипты не всегда безопасны.

§5.5. Внутри сервера ⟶