Как посмотреть окружение браузера
Перейти к содержимому

Как посмотреть окружение браузера

  • автор:

Браузерное окружение, спецификации

Язык JavaScript изначально был создан для веб-браузеров. Но с тех пор он значительно эволюционировал и превратился в кроссплатформенный язык программирования для решения широкого круга задач.

Сегодня JavaScript может использоваться в браузере, на веб-сервере или в какой-то другой среде, даже в кофеварке. Каждая среда предоставляет свою функциональность, которую спецификация JavaScript называет окружением.

Окружение предоставляет свои объекты и дополнительные функции, в дополнение базовым языковым. Браузеры, например, дают средства для управления веб-страницами. Node.js делает доступными какие-то серверные возможности и так далее.

На картинке ниже в общих чертах показано, что доступно для JavaScript в браузерном окружении:

Как мы видим, имеется корневой объект window , который выступает в 2 ролях:

  1. Во-первых, это глобальный объект для JavaScript-кода, об этом более подробно говорится в главе Глобальный объект.
  2. Во-вторых, он также представляет собой окно браузера и располагает методами для управления им.

Например, здесь мы используем window как глобальный объект:

function sayHi() < alert("Hello"); >// глобальные функции доступны как методы глобального объекта: window.sayHi();

А здесь мы используем window как объект окна браузера, чтобы узнать его высоту:

alert(window.innerHeight); // внутренняя высота окна браузера

Существует гораздо больше свойств и методов для управления окном браузера. Мы рассмотрим их позднее.

DOM (Document Object Model)

Document Object Model, сокращённо DOM – объектная модель документа, которая представляет все содержимое страницы в виде объектов, которые можно менять.

Объект document – основная «входная точка». С его помощью мы можем что-то создавать или менять на странице.

// заменим цвет фона на красный, document.body.style.background = "red"; // а через секунду вернём как было setTimeout(() => document.body.style.background = "", 1000);

Мы использовали в примере только document.body.style , но на самом деле возможности по управлению страницей намного шире. Различные свойства и методы описаны в спецификации:

  • DOM Living Standard на https://dom.spec.whatwg.org

DOM – не только для браузеров

Спецификация DOM описывает структуру документа и предоставляет объекты для манипуляций со страницей. Существуют и другие, отличные от браузеров, инструменты, использующие DOM.

Например, серверные скрипты, которые загружают и обрабатывают HTML-страницы, также могут использовать DOM. При этом они могут поддерживать спецификацию не полностью.

CSSOM для стилей

Правила стилей CSS структурированы иначе чем HTML. Для них есть отдельная спецификация CSSOM, которая объясняет, как стили должны представляться в виде объектов, как их читать и писать.

CSSOM используется вместе с DOM при изменении стилей документа. В реальности CSSOM требуется редко, обычно правила CSS статичны. Мы редко добавляем/удаляем стили из JavaScript, но и это возможно.

BOM (Browser Object Model)

Объектная модель браузера (Browser Object Model, BOM) – это дополнительные объекты, предоставляемые браузером (окружением), чтобы работать со всем, кроме документа.

  • Объект navigator даёт информацию о самом браузере и операционной системе. Среди множества его свойств самыми известными являются: navigator.userAgent – информация о текущем браузере, и navigator.platform – информация о платформе (может помочь в понимании того, в какой ОС открыт браузер – Windows/Linux/Mac и так далее).
  • Объект location позволяет получить текущий URL и перенаправить браузер по новому адресу.

Вот как мы можем использовать объект location :

alert(location.href); // показывает текущий URL if (confirm("Перейти на Wikipedia?")) < location.href = "https://wikipedia.org"; // перенаправляет браузер на другой URL >

Функции alert/confirm/prompt тоже являются частью BOM: они не относятся непосредственно к странице, но представляют собой методы объекта окна браузера для коммуникации с пользователем.

Спецификации

BOM является частью общей спецификации HTML.

Да, вы всё верно услышали. Спецификация HTML по адресу https://html.spec.whatwg.org не только про «язык HTML» (теги, атрибуты), она также покрывает целое множество объектов, методов и специфичных для каждого браузера расширений DOM. Это всё «HTML в широком смысле». Для некоторых вещей есть отдельные спецификации, перечисленные на https://spec.whatwg.org.

Итого

Говоря о стандартах, у нас есть:

Спецификация DOM описывает структуру документа, манипуляции с контентом и события, подробнее на https://dom.spec.whatwg.org. Спецификация CSSOM Описывает файлы стилей, правила написания стилей и манипуляций с ними, а также то, как это всё связано со страницей, подробнее на https://www.w3.org/TR/cssom-1/. Спецификация HTML Описывает язык HTML (например, теги) и BOM (объектную модель браузера) – разные функции браузера: setTimeout , alert , location и так далее, подробнее на https://html.spec.whatwg.org. Тут берётся за основу спецификация DOM и расширяется дополнительными свойствами и методами.

Кроме того, некоторые классы описаны отдельно на https://spec.whatwg.org/.

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

Когда вам нужно будет прочитать о каком-то свойстве или методе, справочник на сайте Mozilla https://developer.mozilla.org/ru/ тоже очень хороший ресурс, хотя ничто не сравнится с чтением спецификации: она сложная и объёмная, но сделает ваши знания максимально полными.

Для поиска чего-либо обычно удобно использовать интернет-поиск со словами «WHATWG [термин]» или «MDN [термин]», например https://google.com?q=whatwg+localstorage, https://google.com?q=mdn+localstorage.

А теперь давайте перейдём к изучению DOM, так как страница – это основа всего.

Как узнать браузер javascript

Чтобы узнать какой используется браузер, можно обратиться к специальному объекту window.navigator . У этого объекта есть множество свойств, дающих информацию об используемом агенте(браузере). Вот некоторые из них:

  • appCodeName — внутренний код текущего браузера
  • appName — официальное название браузера
  • appVersion — версия браузера
  • userAgent — полное имя агента браузера

Хочется заметить, что официальная документация не рекомендует обнаруживать пользовательский браузер, так как эта информация может быть ненадёжная. Вы должны понимать какую ставите цель. Например, если вы проверяете браузер, чтобы узнать поддерживает он используемый вами функционал или нет, вы можете вместо проверки браузера проверять реализацию этого функционала и предоставлять альтернативный вариант.

Браузерное окружение, BOM

Один JavaScript в поле не воин — у JavaScript есть окружение, которое делает его таким мощным и популярным.

Время чтения: 7 мин

Открыть/закрыть навигацию по статье

Обновлено 20 сентября 2022

Кратко

Скопировать ссылку «Кратко» Скопировано

Современный JavaScript используется не только в браузерах. Среда, в которой он запускается, будь то браузер, сервер или что-то ещё, называется окружением.

У разных окружений разные возможности и функциональность. В этой статье рассмотрим браузерное окружение и браузерную модель документа.

Окружение предоставляет языку дополнительные возможности и функции. Браузерное окружение, например, даёт возможность работать со страницами сайтов.

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

В случае с браузерным окружением — это объектная модель браузера (Browser Object Model, BOM). Она предоставляет доступ к navigator , location , fetch и другим объектам.

 /* BOM | __________________________|______________________________________ | | | | | |navigator screen location fetch history . */ /* BOM | __________________________|______________________________________ | | | | | | navigator screen location fetch history . */      

navigator

Скопировать ссылку «navigator» Скопировано

Объект navigator содержит информацию о браузере: название, версия, платформа, доступные плагины, доступ к буферу обмена и прочее. Это один из самых больших объектов в окружении.

Так, например, может выглядеть содержимое этого объекта в Safari:

содержимое navigator в Safari

Или, например, так в Chrome:

содержимое navigator в Chrome

С помощью этого объекта можно узнать, разрешён ли доступ к кукам, получить доступ к буферу обмена, геолокации, узнать, с какого браузера пользователь смотрит на страницу через user Agent .

Забавный факт: поле user Agent объекта navigator часто используется, чтобы определять, в каком именно браузере пользователь смотрит страницу сайта. Но читать его глазами достаточно трудно, поэтому лучше это дело оставить какому-нибудь парсеру.

В июне 2021 появился более безопасный инструмент для определения браузера — User-Agent Client Hints. Его цель в том, чтобы позволить определять тип браузера, не оставив возможности для сбора данных о пользователях.

Также с помощью navigator можно зарегистрировать Service Worker.

screen

Скопировать ссылку «screen» Скопировано

Объект screen содержит информацию об экране браузера.

содержимое объекта screen

width и height указывают ширину и высоту экрана в пикселях соответственно. avail — метрики указывают, сколько ширины и высоты доступно — то есть ширину и высоту с учётом интерфейсных деталей браузера типа полос прокрутки.

pixel Depth указывает количество битов на один пиксель экрана.

location

Скопировать ссылку «location» Скопировано

Объект location даёт возможность узнать, на какой странице мы находимся (какой у неё URL) и перейти на другую страницу программно.

Содержимое объекта location

Внутри него есть полезные поля для того, чтобы искать нужную часть адреса.

  • href содержит URL целиком, включая в себя полный адрес хоста, страницы и все query-параметры.
  • host и hostname указывают имя хоста. Разница между ними в том, что host включает в себя порт. Если бы мы стучались не на [google . com ] ( http : / / google . com ) , а на google . com : 8080 , то host содержал бы значение www . google . com : 8080 , в то время как hostname остался бы тем же.
  • pathname указывает путь от корня адреса до текущей страницы.
  • search указывает query-параметры, которые находятся в адресной строке, если они есть.
  • hash указывает хеш (ID элемента после # ) страницы. Его ещё называют якорем, потому что при переходе на страницу с хешем браузер найдёт элемент с ID, равным этому хешу, и прокрутит страницу к этому элементу.

Если мы хотим изменить адрес и перейти на другую страницу, мы можем указать новый location . href :

 location.href = 'https://yandex.ru' location.href = 'https://yandex.ru'      

И браузер перейдёт на страницу с адресом https://yandex.ru.

fetch

Скопировать ссылку «fetch» Скопировано

fetch предоставляет возможность работы с сетью, с его помощью можно отправлять запросы на сервер.

 fetch('http://example.com/movies.json') .then((response) =>  return response.json() >) .then((data) =>  console.log(data) >) fetch('http://example.com/movies.json') .then((response) =>  return response.json() >) .then((data) =>  console.log(data) >)      

history

Скопировать ссылку «history» Скопировано

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

Чтобы перемещаться по истории назад и вперёд, можно использовать методы back ( ) и forward ( ) :

 // Перешли на страницу назадhistory.back() // Перешли на страницу вперёд.history.forward() // Перешли на страницу назад history.back() // Перешли на страницу вперёд. history.forward()      

Для более точного управления историей рекомендуется использовать push State ( ) и replace State ( ) .

Методы push State ( ) и replace State ( ) принимают три параметра:

  • state — любые данные, которые связаны с переходом;
  • unused — неиспользуемый параметр, который существует по историческим причинам;
  • url (необязательный) — url адрес новой записи в истории.
 // state — данные для новой записи в историиconst state = // unused — для совместимости рекомендуется передавать пустую строку:const unused = '' // url — url адрес который будет добавлен в адресную строку:const url = '/another-page/' history.pushState(state, unused, url) // state — данные для новой записи в истории const state =  user_id: 5 > // unused — для совместимости рекомендуется передавать пустую строку: const unused = '' // url — url адрес который будет добавлен в адресную строку: const url = '/another-page/' history.pushState(state, unused, url)      

Браузер «перейдёт» на страницу /another — page / . Перейдёт не по-настоящему, потому что страница не перезагрузится, а лишь сменит адрес в строке. Это удобно при работе с одностраничными приложениями, когда мы не хотим, чтобы страница перезагружалась.

local Storage , session Storage

Скопировать ссылку «localStorage, sessionStorage» Скопировано

Локальные хранилища используются, чтобы хранить какие-то данные в браузере пользователя.

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

Допустим, у нас есть форма из 5 шагов, и мы хотим, чтобы все введённые данные сохранились, и пользователь, закрыв браузер и через какое-то время вернувшись, мог не набирать их заново.

 function saveToStorage(data)  try  window.localStorage.setItem('some-key', JSON.stringify(data)) > catch  alert('Failed to save data to local storage.') >> function loadFromStorage()  try  return JSON.parse(window.localStorage.getItem('some-key')) > catch  alert('Failed to load data from local storage.') >> // Код обработки формы function nextStep()  // При переходе сохраняем всё, что введено: saveToStorage(formData)> function saveToStorage(data)  try  window.localStorage.setItem('some-key', JSON.stringify(data)) > catch  alert('Failed to save data to local storage.') > > function loadFromStorage()  try  return JSON.parse(window.localStorage.getItem('some-key')) > catch  alert('Failed to load data from local storage.') > > // Код обработки формы function nextStep()  // При переходе сохраняем всё, что введено: saveToStorage(formData) >      

Разница между local Storage и session Storage в длительности хранения данных. Данные из session Storage сотрутся, когда пользователь закроет вкладку с приложением. Данные же из local Storage не стираются сами по себе.

На практике

Скопировать ссылку «На практике» Скопировано

Отслеживание параметров браузера и ОС пользователя как мера предотвращения угона аккаунтов (обновлено)

image

Многие он-лайн сервисы стремятся обезопасить аккаунты своих пользователей самыми различными способами. Кто-то отслеживает IP-адрес, сбрасывая кукисы при его изменении (так происходит на Секлабе; вКонтакте просто просит подтвердить последние 4 цифры мобильника). У кого-то сессия живёт ограниченное время, заставляя пользователя авторизоваться снова и снова. У этих способов есть свои достоинства и недостатки. Но какой бы из механизмов не использовался, отслеживание параметров браузера и ОС пользователя придаст дополнительную защиту от угона аккаунтов (как дополнительная защита, но ни в коем случае не основная). И очень странно, что я до сих пор не смог встретить ни одного сервиса, поддерживающего этот механизм защиты.

Задайтесь вопросом: в каких случаях при очередном посещении ресурса у пользователя кукисы будут аналогичны прошлому посещению, но изменятся данные браузера и используемой ОС (которые можно выцепить из User-Agent)? Только в 3-х случаях:

1. Пользователь авторизовался с разных компьютеров (например, дома и на работе) и по некоторым причинам использует разные браузеры.
2. Пользователь авторизовался с 1 компьютера в разных браузерах (этим будут страдать, пожалуй, только веб-разработчики и особо любопытные). Либо те, кто загаживает ОС непонятными фенечками (привет любителям vkSaver)
3. У пользователя угнали сессию.

Детектить предлагается не весь параметр User-Agent, а тип браузера (IE, FF, Chrome, Safari и т.д.) и операционную систему (Windows, Linux, MacOS). Это решит проблемы ложного срабатывания при обновлении ПО на компе пользователя.

Да, User-Agent можно подменять. Но:
1. Довольно часто с этим никто из угонщиков сессии не парится.
2. Подмену User-Agent можно определить (читайте ниже как).

Рассмотрим предлагаемый метод защиты в дополнение к имеющимся. В совокупности с классическими случаями угона сессии.

Отслеживание изменения IP адреса

Это хорошая практика. Но не поможет, если у пользователя нету мозгов хватило ума заходить на свой аккаунт через беспроводную сеть, где его сессию и прослушали. Либо он стал жертвой атаки «человек посередине» от злоумышленника, находящегося в одной подсети с ним у провайдера (не смейтесь, случай хоть и бородатый, но всё ещё частенько встречающийся). Скорее всего, злоумышленник не будет париться с изменением User-Agent. На то мы и рассчитываем. В итоге, доп защита срабатывает.

Сессия живёт ограниченное время

Ну мало того, что это неудобно для пользователя (часто авторизоваться). Так ещё и ситуация абсолютно аналогична предыдущей. И опять же: изменение User-Agent может быть чётким сигналом попытки угона сессии.

А что делать тем, кто всё-таки пользуется разными браузерами дома и на работе?

Как вариант, можно одну из переменных cookies генерить на основа User-Agent. Т.к. злоумышленники довольно часто копируют себе все cookies сервера без разбора, то тут-то они и попалятся, скопировав себе и переменную, привязанную для другого User-Agent.

«Ну, подменить User-Agent труда не составит, с этим только школота недостаточно опытные взломщики не справятся»,

— скажет тут кто-то их посетителей.

image

image

Действительно, кому нужно — тот сможет подменить. Но на помощь приходит интересный способ определения браузера через javascript. Метод очень действенный, сам проверял.

Хотя, и этот способ можно обойти: т.к. javascript выполняется в браузере, на стороне пользователя (потенциального злоумышленника), то мы можем контролировать его выполнение и, тем самым, обойти проверку (Firebug как один из вариантов). Но об этом нужно чётко знать. К тому же, обфусцированность скрипта сильно затруднит задачу.

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *