Category: it

Category was added automatically. Read all entries about "it".

HTML: новые и старые особенности работы со ссылкой

Хоть разработка стандарта языка HTML версии 5 была завершена и стандарт был рекомендован к использованию организацией «W3C» в относительно далёком на сегодня 2014 году, для меня он до сих пор является новым и знаю я его довольно слабо. (Сейчас, кстати, разработчики стандарта языка HTML, насколько я знаю, отказались от четкого деления на версии в дальнейшей разработке стандарта. Изменения в стандарт вносятся постоянно, поэтому теперь его называют «Живым стандартом» [по-английски «Living Standard»]. «Живой» — в смысле, что он находится в состоянии постоянного изменения.)

В этом посте я хочу разобрать некоторые (не все) новые и старые особенности работы со ссылкой (HTML-элементом a).

* * *

Оказывается, HTML версии 5 добавил в HTML-элемент a атрибут download. Если у данного HTML-элемента есть этот атрибут, то при нажатии на ссылку пользователь запустит не переход по ссылке, а загрузку файла, адрес которого указан в атрибуте href данного HTML-элемента. Пример кода на языке HTML:
<a href="file.jpg">Открыть файл в браузере</a>
<a href="file.jpg" download>Скачать файл</a>

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

При использовании указанного выше кода при запуске загрузки файла предполагается, что файл будет сохранен на компьютере пользователя под именем file.jpg. Однако, в атрибуте download можно указать имя, под которым файл будет сохранен на компьютере пользователя. Пример кода:
<a href="file.jpg" download="image.jpg">Скачать файл</a>
В этом примере браузер (если пользователь нажмет на эту ссылку) должен скачать файл file.jpg и сохранить его на компьютере пользователя под именем image.jpg.

https://developer.mozilla.org/en-US/docs/Web/HTML/Element/A
http://htmlbook.ru/html/a/download

* * *

Еще одно новое для меня изменение в стандарте HTML версии 5 заключается в том, что несколько изменился способ создания якоря (закладки) на HTML-странице. Ранее это можно было делать следующим образом:
<a href="#anchor">Ссылка на якорь</a>
<!-- ... -->
<a name="anchor">Текст, на который поставлен якорь</a>

Этот способ работает в браузере и сегодня (как я понимаю, он оставлен для обратной совместимости). Однако, стандарт HTML версии 5 не одобряет (осуждает, по-английски такие атрибуты называются «deprecated») использование атрибута name для HTML-элемента a. Вместо него в данном случае предлагается использовать глобальный атрибут id. Пример кода:
<a href="#anchor">Ссылка на якорь</a>
<!-- ... -->
<a id="anchor">Текст, на который поставлен якорь</a>


* * *

Рассмотрим такой пример кода на языке HTML:
<a href="">Ссылка на текущую HTML-страницу</a>
<a href="#">Ссылка на текущую HTML-страницу</a>

Обе эти ссылки ссылаются на текущую HTML-страницу. Но между ними есть важное отличие: при нажатии на первую ссылку браузер перезагрузит (обновит) текущую HTML-страницу, а при нажатии на вторую ссылку браузер не станет перезагружать (обновлять) текущую HTML-страницу. Поэтому именно вторую ссылку некоторые программисты используют для создания кнопок на HTML-странице (вообще, такой способ создания кнопок не рекомендуется использовать, для кнопок следует использовать HTML-элемент button).

А что произойдет, если к этим ссылкам добавить вышеописанный атрибут download?
<a href="" download>Ссылка на текущую HTML-страницу</a>
<a href="#" download>Ссылка на текущую HTML-страницу</a>

Между двумя такими ссылками разницы не будет: при нажатии на любую из них произойдет одно и то же действие — браузер должен будет запустить загрузку текущей HTML-страницы на компьютер пользователя (по умолчанию — в соответствующую папку для загрузок, в файл с именем, совпадающим с названием HTML-страницы).

Капля: от фантастического ужаса до программирования

Помню, в детстве посмотрел американский фильм «Капля» («The Blob») 1988 года в жанре фантастических ужасов. Он произвел на меня большое впечатление. [вики, кинопоиск]



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

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

А еще позднее я прочел фантастический роман «Клон» («The Clone») 1965 года американских авторов Теодора Томаса (Theodore L. Thomas) и Кейт Вильгельм (Kate Wilhelm):
http://www.lib.ru/INOFANT/TOMAS/clon.txt

В 1966 году этот роман был номинирован на известную ежегодную премию «Небьюла» (это был первый год награждения этой премией, она была учреждена в 1965 году) в категории «за лучший роман» (всего номинантов было 12), но уступил знаменитой «Дюне» Фрэнка Герберта.

Роман «Клон» родился из одноименного фантастического рассказа Теодора Томаса, опубликованного в декабре 1959 года в журнале «Fantastic», который издавался в США в период с 1952 года по 1980 год. Вероятно, Теодор Томас вдохновлялся фильмом «The Blob» 1958 года.

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

Слово «blob» переводится на русский с английского как «капля», «сгусток», «комочек».

* * *

Использовать слово «blob» для обозначения больших аморфных кусков двоичных данных придумал разработчик реляционных систем управления базами данных Джим Старки (Jim Starkey) во время своей работы на американскую компьютерную компанию «DEC» во второй половине 1970-х.

Джим Старки вдохновлялся в том числе вышеописанным фильмом «The Blob» 1958 года. Подробнее об этом можно почитать в википедии и в «Архиве Интернета» (там есть тексты электронных писем самого Джима Старки и его супруги Энн Харрисон [Ann Harrison]):

https://ru.wikipedia.org/wiki/BLOB
https://en.wikipedia.org/wiki/Binary_large_object
https://en.wikipedia.org/wiki/Jim_Starkey
https://web.archive.org/web/20110723065224/http://www.cvalde.net/misc/blob_true_history.htm

Изначально слово «blob» использовалось в программировании на уровне сленга. Но позже для него придумали бэкроним (обратная аббревиатура), то есть придумали аббревиатуру под имеющийся термин (обычно всё происходит наоборот: для часто использующегося словосочетания придумывают аббревиатуру). Слово «blob» превратилось в аббревиатуру «BLOB» и вошло в программирование в качестве термина. Сейчас аббревиатура «BLOB» расшифровывается как «Binary Large Object» (по-русски «двоичный большой объект»).

В языке JavaScript есть встроенный объект Blob, который, как и амёбообразный монстр в вышеупомянутом кино, может поглощать в себя передаваемые ему объекты типа Blob, строки и бинарные массивы вроде ArrayBuffer, Uint8Array и так далее, образуя коллекцию (массив) двоичных данных.

Браузер: настройка загрузки файлов

Читаю сейчас подраздел 2.3 «Blob» третьей части учебника по JavaScript. Нахожу в нем очень много нового для себя. В частности, возник вопрос: как в браузере можно настраивать загрузку файлов?

Я пользуюсь браузером «Microsoft Edge» на движке «Chromium», поэтому далее буду излагать этот вопрос на примере именно этого браузера. (Для других браузеров, построенных на этом же движке [например, для того же «Google Chrome»], думаю, настройки должны быть примерно такими же.) Кроме этого, наверное, стоит отметить, что у меня на компьютере установлена операционная система «Windows 10 Pro».

Настройки браузера я могу открыть в открытом окне браузера с помощью комбинации клавиш «Alt+F» или с помощью кнопки с многоточием в правом верхнем углу окна браузера. В меню этих настроек можно найти и нажать пункт «Downloads» (по-русски «Загрузки»), а еще этот пункт можно вызывать с помощью комбинации клавиш «Ctrl+J». Еще этот пункт можно вызвать с помощью кнопки со стрелкой вниз на панели инструментов браузера, но ее там может и не быть (наличие или отсутствие этой кнопки на панели инструментов браузера тоже может быть настроено).

После открытия пункта «Downloads» появится небольшое окошко, основную часть которого занимает список загруженных (и загружаемых) файлов. Это окошко может открываться само при попытке загрузить файл (но может и не открываться, это тоже настраивается).

В верхней части этого окошка есть заголовок «Downloads», нажав на который можно открыть отдельную вкладку в браузере с тем же списком загруженных (и загружаемых) файлов, но в отдельной вкладке браузера с этим списком работать удобнее. Также эту отдельную вкладку можно открыть в браузере, написав в адресной строке следующее:
edge://downloads

Из окошка (или вкладки браузера) «Downloads» можно установить, какие файлы были загружены (загружаются в данный момент) и куда они были сохранены (сохраняются в данный момент).

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

Список загруженных (загружаемых) файлов в любой момент можно очистить (это не удалит сами загруженные файлы). Это называется «Clear all download history» (по-русски «Стереть историю загрузок»).

Настройки загрузки файлов можно открыть из окошка «Downloads», нажав на кнопку с многоточием в этом окошке (эта кнопка называется «More options» или по-русски «Дополнительные опции»). Также эту кнопку можно нажать в описанной ранее вкладке «Downloads» браузера. В открывшемся меню следует выбрать пункт «Downloads settings» (по-русски «Настройки загрузок»). При выборе этого пункта меню откроется отдельная вкладка браузера с настройками. Еще эту вкладку браузера можно открыть в браузере, написав в адресной строке следующее:
edge://settings/downloads

Четвертый способ открыть вкладку браузера с этими настройками — открыть, собственно, настройки браузера (это тоже можно сделать несколькими способами). Откроется отдельная вкладка браузера с адресом:
edge://settings
И уже на этой вкладке выбрать в меню слева пункт «Downloads». Откроется та же самая вкладка браузера с настройками загрузок, описанная выше.

На вкладке браузера с настройкой загрузок файлов есть на сегодня (браузеры постоянно находятся в разработке, поэтому всё описанное здесь может в любой момент устареть) четыре пункта:

1) «Location» (по-русски «Папка по умолчанию, в которую загружаются файлы»). Тут можно изменить папку, в которую по умолчанию загружаются файлы;

2) «Ask me what to do with each download» (по-русски «Спрашивать меня, что делать с каждой загрузкой»). Если эта опция включена, при начале загрузки каждого файла браузер откроет окошко загрузок, а в нем выведет вопрос, что делать с данным файлом.

Тут можно отказаться от загрузки файла, нажав крестик в правом верхнем углу окна вопроса. Либо можно выбрать пункт «Open» (по-русски «Открыть»), в этом случае браузер загрузит файл, сохранит его в своей служебной папке и сразу же откроет этот файл соответствующей программой. Либо можно выбрать пункт «Save as» (по-русски «Сохранить как»), тогда браузер выведет окно, в котором можно будет выбрать папку для загрузки и хранения данного файла. Либо можно выбрать пункт «Save» (по-русски «Сохранить»), тогда браузер загрузит данный файл и сохранит его в папку по умолчанию из вышеописанного пункта «Location».

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

3) «Open Office files in the browser» (по-русски «Автоматически открывать офисные файлы в браузере, а не скачивать их в папку»). Под офисными файлами, как я понимаю, подразумеваются файлы, созданные для офисного пакета приложений «Microsoft Office» (таблицы, презентации, документы и так далее).

4) «Show downloads menu when a download starts» (по-русски «Открывать окошко «Downloads» при начале загрузки файла»). У меня эта опция включена, так как я хочу сразу знать, если браузер начнет загружать какой-либо файл на мой компьютер.

Выводы. Программист может на какой-либо HTML-странице с помощью скрипта на языке JavaScript (или с помощью конструкций на языке HTML) дать возможность пользователю запустить загрузку какого-либо файла к себе на компьютер, либо даже запустить загрузку какого-либо файла на компьютер пользователя без отмашки пользователя.

При этом браузер может либо вообще никак не показать пользователю, что началась загрузка некоего файла на его компьютер, либо браузер может сообщить об этом пользователю: всё зависит от настройки браузера.

JavaScript: TextDecoder и TextEncoder, UTF-8

Прочел подраздел 2.2 «TextDecoder и TextEncoder» третьей части учебника по JavaScript.

В большинстве случаев авторы данного учебника расписывают свои уроки довольно подробно и понятно. Однако, иногда они становятся чересчур лаконичны. И тут такой случай. Два фрагмента кода из учебника:

let uint8Array = new Uint8Array([72, 101, 108, 108, 111]);

alert( new TextDecoder().decode(uint8Array) ); // Hello

let uint8Array = new Uint8Array([228, 189, 160, 229, 165, 189]);

alert( new TextDecoder().decode(uint8Array) ); // 你好

Во-первых, следовало бы отметить, что «你好» — это знаменитое «ни хао», то есть «привет» по-китайски или «hello» по-английски. Без этой ремарки лично мне было не очень понятно, зачем в этом примере эти два китайских иероглифа. Ну и следовало бы отметить, что этих иероглифов тут именно два, это важно. С первого взгляда для нашего, русского, глаза непонятно, сколько в этой надписи символов.

Во-вторых, следовало бы немного пояснить за кодировку. Я, конечно, уже немного ориентируюсь в Юникоде и знаю про существование одного из его форматов UTF-8 (для встроенных объектов TextDecoder и TextEncoder этот формат является форматом по умолчанию). Однако, подробно я разбирался с Юникодом только на примере формата UTF-16LE (тут), для него в операционной системе «Windows» в большинстве случаев всё достаточно просто: все символы представляются двумя байтами.

Для формата UTF-8, однако же, всё не так просто. Легко читать только первые 128 кодов Юникода, которые совпадают с ASCII и содержат все символы латинского алфавита. В UTF-8 они кодируются одним байтом. Поэтому в вышеприведенном примере фраза «Hello» кодируется и декодируется так легко: [72, 101, 108, 108, 111] это и есть «H», «e», «l», «l», «o» (каждый из этих кодов меньше 128).

Но для остальных кодов Юникода в формате UTF-8 используется переменное число байтов: от двух до четырех. Для вышеприведенных китайских иероглифов в формате UTF-8 используется по три байта:

228, 189, 160 — это «你»
229, 165, 189 — это «好»

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

https://ru.wikipedia.org/wiki/UTF-8

Как при декодировании строки в формате UTF-8 понять, сколько байтов представляет очередной символ? Для этого считывается первый байт из буфера и анализируются его старшие биты (нам это делать не нужно, это делает встроенный в JavaScript объект, но важно понимание процесса). В нашем примере берем первый байт из буфера:

22810 = 111001002

Если старший бит (самый левый) равен нулю (не наш случай), то этот байт является однобайтным представлением символа. Если старший бит равен единице, переходим к соседнему биту справа. Если этот бит равен нулю (не наш случай), значит данный байт является одним из многобайтового представления символа, но не первым. И так далее. Вот шаблоны для анализа (иксами обозначены биты, в которых содержится, собственно, код из таблицы Юникода):

0xxxxxxx — байт однобайтового представления символа;
10xxxxxx — байт многобайтового представления символа (не первый);
110xxxxx — первый байт двухбайтового представления символа;
1110xxxx — первый байт трехбайтового представления символа;
11110xxx — первый байт четырехбайтового представления символа.

В нашем случае подходит шаблон 1110xxxx, следовательно, это первый байт трехбайтового представления символа. Далее движок считывает три байта: 228, 189, 160 и определяет по таблице Юникода, что это символ «你». И так далее.

Вот моя любимая таблица Юникода в интернете:
https://unicode-table.com/ru/

Вот для примера страница символа-иероглифа «你» на этом сайте (там приведены десятичные, шестнадцатиричные и двоичные коды этого символа в разных форматах Юникода):
https://unicode-table.com/ru/4F60/

Этот символ содержится в разделе таблицы Юникода, который называется «Унифицированные идеограммы ККЯ — расширение F» (по-английски «CJK Unified Ideographs Extension F»). «Идеограммами» названы иероглифы. Аббревиатура «ККЯ» расшифровывается как «Китайский, Корейский, Японский» (на самом деле, там еще есть и вьетнамские иероглифы, так что должно быть «ККЯВ»). Тут подробнее:
https://ru.wikipedia.org/wiki/Унифицированные_идеограммы_ККЯ_—_расширение_F

JavaScript: работа с бинарными данными, типизация

Прочел подраздел 2.1 «ArrayBuffer, бинарные массивы» третьей части учебника по JavaScript.

Классная статья, очень понравилась. Соскучился я по строгой типизации. Мне понравился подход к этой теме со стороны программистов на JavaScript.

Если в языке программирования C++, который я изучил раньше, учебники подходят к теме хранения данных в памяти как бы «снизу вверх» (потому что их написали сишники, которые пришли в объектно-ориентированное программирование, а некоторые из них сами придумали это самое ООП), то в учебнике по JavaScript обучение приходит от переменных без типа к работе с бинарными данными, то есть как бы «сверху вниз». Через это, как мне кажется, объяснения получились гораздо понятнее. Тут даже объяснено, что такое «буфер» и как это понятие соотносится с понятием «массив» (для сишников «буфер» — это настолько привычный термин, что никому из них в голову даже и не придет мысль его объяснять).

В комментариях к этой статье, кстати, довольно много вопросов типа «а зачем эта фигня может понадобится?», что показывает, насколько далеко «фронтенд» оторвался от реальности...

К статье есть несложная задача. Она называется «Соедините типизированные массивы». Дан массив arrays типизированных массивов типа Uint8Array (это массив, для хранения каждого элемента которого выделен один байт памяти; этот байт интерпретируется как беззнаковое целое число, то есть в нем могут храниться целые числа в диапазоне 0..255). Требуется написать функцию concat(arrays), которая вернет одномерный массив типа Uint8Array, который будет содержать элементы всех массивов из заданного массива arrays.

Я ее решил, ниже описан ход решения.

Сначала сформируем структуру входных данных, с помощью которых будем тестировать будущую функцию concat. Пишем код:
// массивы, которые требуется соединить в один одномерный массив
let arr8_1 = new Uint8Array([0, 1, 2, 3]);
let arr8_2 = new Uint8Array([4, 6, 8]);
let arr8_3 = new Uint8Array([]);

// входные данные для тестирования нашей функции
let arrays = [arr8_1, arr8_3, arr8_2];

Вообще в задаче не указано количество объединяемых массивов, то есть оно может быть любым. Но я решил взять три массива: arr8_1, arr8_2, arr8_3. Длина каждого из объединяемых массивов в задаче тоже не указана, значит, она тоже может быть любой. Для моих трех массивов эта длина соответственно будет 4, 3 и 0. Эти три массива могут быть помещены в массив arrays в любом порядке, но нужно понимать, что от этого зависит порядок элементов в итоговом объединенном массиве.

Добавим код требуемой функции concat. У меня он получился таким, но, конечно, может быть много других вариантов.
// массивы, которые требуется соединить в один одномерный массив
let arr8_1 = new Uint8Array([0, 1, 2, 3]);
let arr8_2 = new Uint8Array([4, 6, 8]);
let arr8_3 = new Uint8Array([]);

// входные данные для тестирования нашей функции
let arrays = [arr8_1, arr8_3, arr8_2];

function concat(arrays) {
    let result = [];
    for (let i = 0; i < arrays.length; i++) {
        for (let j = 0; j < arrays[i].length; j++) {
            result.push(arrays[i][j]);
        }
    }
    return new Uint8Array(result);
}

// тестируем функцию и выводим результат на экран
alert( concat(arrays) );

Как работает код этого варианта функции concat? Мы создаем обычный для языка JavaScript пустой одномерный массив result и переписываем в него значения элементов заданных для объединения типизированных массивов. После этого преобразуем обычный массив result в типизированный и возвращаем получившийся массив.

Этот мой вариант кода функции concat успешно прошел автоматические тесты от авторов задачи. Тестов там три: 1) возвращенный функцией массив должен быть нужного типа Uint8Array; 2) возвращенный массив должен быть объединением заданных массивов; 3) в случае, если функция получает в качестве входящего параметра пустой массив, она должна вернуть пустой массив.

Учебник по JavaScript, ч.3: Фреймы и окна, кликджекинг

Прочел первый раздел «Фреймы и окна» третьей части («Тематические разделы») учебника по JavaScript.

https://learn.javascript.ru

Часть 3. Тематические разделы (в т.ч. 66 подразделов)

Разделы:

1. Фреймы и окна (3 подраздела)

1.1 Открытие окон и методы window
1.2 Общение между окнами
1.3 Атака типа clickjacking

Отделение первой части учебника, в принципе, понятно. Там изучался, собственно, сам язык JavaScript. Смысл разделения оставшихся статей учебника на вторую и третью части менее очевиден. Нельзя сказать, что статьи третьей части учебника менее важны, чем статьи второй части. Так что граница между ними, скорее, косметическая.

Задач к этому разделу нет, зато есть множество примеров кода.

Рассказано, как из JavaScript работать с окнами в браузере. Под «окнами» здесь подразумеваются как «всплывающие окна» (по-английски «pop-up») и вкладки браузера, так и содержимое фреймов. Для реализации последних раньше использовали HTML-элементы frame и frameset, но на сегодня их использование не рекомендуется, вместо них предлагается использовать HTML-элемент iframe. Рассказано о механизме блокировки всплывающих окон браузера и о том, как он работает.

В подразделе 1.2 рассказано, как наладить общение между окнами с помощью языка JavaScript и о том, как при этом обеспечивается безопасность с помощью политики одинакового источника (по-английски «same-origin policy»).

В подразделе 1.3 рассказано про способ обмана пользователей, который называется кликджекингом (по-английски «clickjacking»).

https://ru.wikipedia.org/wiki/Кликджекинг
https://en.wikipedia.org/wiki/Clickjacking

Почему об этом способе обмана вообще рассказывается в учебнике по языку JavaScript и почему о нем рассказывается именно в этом месте учебника? Потому что этот способ легко реализовать с помощью скрипта на языке JavaScript вкупе с кодом на языках HTML и CSS на HTML-странице. При этом может использоваться HTML-элемент iframe. В подразделе 1.3 рассказано о методах противодействия этому способу обмана. Чтобы разобраться в том, как работает этот способ обмана и в методах противодействия, нужно понимание работы с окнами в языке JavaScript.

Как работает этот способ обмана? Злоумышленник заманивает пользователя на свою HTML-страницу. На этой странице есть некий элемент интерфейса, на который предлагается нажать, чтобы что-то получить (например, кнопка для скачивания какого-либо файла и тому подобное). Пользователь нажимает мышкой («кликает») на этот элемент интерфейса. Но он не знает, что над этим элементом интерфейса растянут невидимый HTML-элемент iframe, в котором загружена другая HTML-страница.

Получается, под щелчок мышкой пользователя («клик») незаметно подкладывается другая HTML-страница («джекинг»). Эта другая HTML-страница может быть, к примеру, HTML-страницей в социальной сети, в которой данный пользователь зарегистрирован (или HTML-страницей банка, в котором данный пользователь имеет счет). Злоумышленник может незаметно подставить под щелчок мышкой пользователя кнопку лайка какого-то поста в социальной сети (это еще не так страшно) или кнопку отправки платежа в каком-нибудь интернет-магазине (это уже серьезнее).

Почему этот метод обмана срабатывает, если злоумышленник не имеет на руках ни логина, ни пароля пользователя? Дело в том, что многие пользователи, покидая какой-либо интернет-сервис, не выполняют выхода из него (например, просто закрывают HTML-страницу интернет-сервиса, при этом остаются залогинеными). При таком раскладе злоумышленнику достаточно незаметно подставить пользователю кнопку того интернет-сервиса, из которого пользователь не совершил выхода (разлогина).

Как злоумышленник угадывает, что данный пользователь вообще имеет аккаунт на определенном интернет-сервисе и что он не разлогинился на этом интернет-сервисе? Злоумышленник не угадывает, а просто «работает по площадям». Например, злоумышленник знает, что огромное количество пользователей имеет аккаунт, к примеру, на фейсбуке и не разлогинивается оттуда. Он заманивает всех, кого удастся, на свою HTML-страницу и подставляет с помощью кликджекинга, к примеру, кнопку лайка поста, который он хочет продвинуть в этой социальной сети. Те, у кого нет аккаунта в фейсбуке, или те, кто разлогинился при выходе из фейсбука, могут попасться на уловку и совершить нажатие мышкой, но это ничего не принесет злоумышленнику, обман не сработает. А вот для тех, у кого есть аккаунт в фейсбуке и кто не разлогинился на момент попадания в ловушку, обман сработает.

Естественно, большинство крупных интернет-сервисов типа фейсбука, твиттера и так далее, на сегодня уже защищены от кликджекинга. В подразделе 1.3 рассказано, какие есть способы защиты и как они работают.

Мои посты по 2-й части учебника learn.javascript.ru

2021 год

1. Учебник по JavaScript: как устроены примеры, движок учебника, Prism.js
2. Учебник по JavaScript: ошибка в примере, eval, use strict
3. JavaScript: порядок выполнения скриптов и модулей на HTML-странице
4. JavaScript: DOM-дерево, консоль разработчика, переменные $0-$4
5. Учебник по JavaScript: 2 часть, нужно знание HTML и CSS, CSS-селекторы
6. Учебник по JavaScript: структуры данных
7. Учебник по JavaScript, структура данных «дерево»
8. Что такое обход дерева
9. Обход дерева в глубину без рекурсии
10. Обход дерева в глубину с рекурсией

11. Обход дерева в глубину, алгоритмы NLR из википедии
12. Обход дерева в глубину, обратный обход (от листьев)
13. HTML-дерево из объекта, рекурсивный способ
14. HTML-дерево из объекта, итеративный способ
15. HTML-дерево из объекта, рекурсия, innerHTML
16. HTML-дерево из объекта, итерации, innerHTML
17. JavaScript: добавление (append) HTML-элементов на страницу
18. JavaScript: задача подсчета элементов в ветках списка
19. JavaScript: задача по созданию HTML-календаря
20. JavaScript: создание цветных часов

21. JavaScript: сортировка строк в HTML-таблице
22. JavaScript: стили и классы, CSS-позиционирование
23. Можно ли использовать HTML-элемент style внутри body?
24. Стилизация по умолчанию от браузера
25. CSS: границы вида groove и ridge, значение initial
26. JavaScript: мяч на футбольном поле
27. JavaScript: координаты углов поля
28. JavaScript: заметка рядом с элементом
29. JavaScript: заметка рядом с элементом 2
30. JavaScript: заметка рядом с элементом 3

31. Учебник по JavaScript, ч.2: Документ
32. CSS: абсолютное позиционирование и содержащий блок
33. JavaScript: гоняю мяч по полю, CSS-анимация
34. JavaScript: плющим мяч, язык SVG
35. JavaScript: раскрывающееся меню
36. JavaScript: дерганье меню, шрифты в браузере
37. JavaScript: кнопки удаления сообщений
38. JavaScript: карусель картинок, строим каркас 1
39. JavaScript: карусель картинок, строим каркас 2
40. JavaScript: карусель картинок, функции для кнопок

41. Учебник по JavaScript: ч.2: Введение в события
42. JavaScript: подсказки к HTML-элементам
43. JavaScript: тонкости работы с событиями мыши
44. Правильная постановка задачи это половина ее решения
45. JavaScript: умная подсказка, разбор постановки задачи
46. Название тестового фреймворка Mocha
47. JavaScript: умная подсказка, подключение автоматических тестов
48. JavaScript: умная подсказка, пять автоматических тестов
49. JavaScript: умная подсказка, начало решения задачи
50. JavaScript: умная подсказка, окончание решения задачи

51. CSS: схлопывание внешних отступов
52. JavaScript: слайдер (ползунок)
53. JavaScript: событие mouseup за пределами HTML-элемента
54. JavaScript: mousedown, preventDefault, iframe
55. JavaScript: расставить героев на поле, постановка задачи
56. JavaScript: расставить героев на поле, решение задачи
57. GIMP, формат PNG, утилита pngcrush
58. Новая версия файла heroes.png
59. JavaScript: одновременное нажатие клавиш
60. JavaScript: бесконечная страница

61. JavaScript: кнопка вверх, кнопка вниз
62. JavaScript: предотвращение кэширования файла
63. JavaScript: загрузка видимых изображений
64. Учебник по JavaScript, ч.2: Интерфейсные события
65. JavaScript: редактируемый div
66. HTML: элемент LINK в теле страницы
67. JavaScript: редактирование TD по клику
68. JavaScript: двигаем элемент стрелками клавиатуры
69. JavaScript: задача про депозитный калькулятор
70. Инструмент разработчика Issues в браузере

71. Настройка веб-сервера из набора IIS, web.config, заголовки HTTP
72. Адаптация HTML-страницы для мобильника 2
73. CSS: схлопывание внешних отступов 2
74. JavaScript: модальное диалоговое окно из HTML-формы (каркас)
75. JavaScript: модальное диалоговое окно из HTML-формы (стили CSS)
76. JavaScript: модальное диалоговое окно из HTML-формы (решение задачи)
77. Учебник по JavaScript, ч.2: Формы, элементы управления
78. Как решать задачи: понимание
79. JavaScript: предзагрузка изображений
80. JavaScript: предзагрузка изображений, упрощаю код

81. Учебник по JavaScript, ч.2: Загрузка документа и ресурсов
82. Учебник по JavaScript, ч.2: наблюдатель, выделение, событийный цикл

Учебник по JavaScript, ч.2: наблюдатель, выделение, событийный цикл

Прочел шестой раздел «Разное» второй части («Браузер: документ, события, интерфейсы») учебника по JavaScript.

https://learn.javascript.ru

Часть 2. Браузер: документ, события, интерфейсы (в т.ч. 32 подраздела)

Разделы:

6. Разное (3 подраздела)

6.1 MutationObserver: наблюдатель за изменениями
6.2 Selection и Range
6.3 Событийный цикл: микрозадачи и макрозадачи

Этот раздел завершает вторую часть учебника. Сюда, как я понимаю, попали темы, которые не получилось вставить в другие разделы. Но попадание в этот раздел, однако, не делает затронутые темы второстепенными. Здесь рассмотрены достаточно важные вопросы.

В подразделе 6.1 описывается встроенный объект MutationObserver, с помощью которого можно следить за изменениями в любом из узлов DOM-дерева. С помощью параметров можно настроить то, за какими конкретно изменениями в указанном узле следует следить. После получения сигнала об изменениях мы можем обработать эти изменения (или сделать что-то другое) так, как нам будет нужно.

В подразделе 6.2 подробно (с большими примерами кода) описана работа с выделениями на HTML-странице (а также с выделениями внутри элементов HTML-форм). Вообще на HTML-странице можно выделять фрагменты текста, картинки и разные HTML-элементы. Именно об этих «выделениях» идет речь. По-английски «выделение» звучит как «selection».

В подразделе 6.3 рассказано про то, как браузер работает с разными задачами, которые ему приходится выполнять. Все задачи попадают в очередь, из которой их извлекает браузер для обработки. Задачи бывают разного типа: макрозадачи, микрозадачи, задача «рендеринга» (отрисовка HTML-страницы при отображении в окне браузера). Рассказано, как и в каком порядке браузер выполняет разные типы задач. По-моему, очень интересная тема. Для лучшего понимания, думаю, следует перечитать хотя бы подразделы 11.2 «Промисы» и 11.7 «Микрозадачи» из первой части учебника, а еще лучше — перечитать весь раздел 11 «Промисы, async/await» первой части учебника.

Больших и интересных задач к этому разделу не завезли, есть только маленькая задачка-вопрос к подразделу 6.3. Зато много больших примеров кода, которые можно скопировать себе в редактор и погонять в браузере для лучшего усвоения.

Учебник по JavaScript, ч.2: Загрузка документа и ресурсов

Прочел пятый раздел «Загрузка документа и ресурсов» второй части («Браузер: документ, события, интерфейсы») учебника по JavaScript.

https://learn.javascript.ru

Часть 2. Браузер: документ, события, интерфейсы (в т.ч. 32 подраздела)

Разделы:

5. Загрузка документа и ресурсов (3 подраздела)

5.1 Страница: DOMContentLoaded, load, beforeunload, unload
5.2 Скрипты: async, defer
5.3 Загрузка ресурсов: onload и onerror

Информация из этих подразделов нужна была мне при чтении учебника гораздо раньше.

Например, при изучении модулей в первой части учебника:
JavaScript: Политика одинакового источника и CORS

А также при начале изучения второй части учебника:
JavaScript: порядок выполнения скриптов и модулей на HTML-странице

Думаю, авторам учебника в связи с этим следует как-то немного перестроить порядок подразделов полностью или частично.

К этому разделу учебника есть только одна задача. Я разобрал ее решение в двух постах:
1. JavaScript: предзагрузка изображений
2. JavaScript: предзагрузка изображений, упрощаю код