«Поиск недостатков и заполнение утечек» отправит вам 18 вопросов браузерного интервью.

JavaScript
«Поиск недостатков и заполнение утечек» отправит вам 18 вопросов браузерного интервью.

предисловие

Если вы хотите стать квалифицированным фронтенд-инженером, необходимо освоить принципы работы соответствующих браузеров. Только так у вас будет полная система знаний. Если вы можете понять принципы работы браузеров, вы сможете решить 80 % проблем с интерфейсом. проблема".

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

Спасибо за вашу поддержку и поддержку🌹🌹🌹, предыдущие статьи разобраны в конце (●'◡'●)


"Далее будет разбирать в виде вопросов"

1. Каковы распространенные ядра браузеров?

Браузер/среда выполнения ядро (движок рендеринга) JavaScript-движок
Chrome webkit->blink V8
FireFox Gecko SpiderMonkey
Safari Webkit JavaScriptCore
Edge EdgeHTML Chakra(for JavaScript)
IE Trident JScript (IE3.0-IE8.0)
Opera Presto->blink Линейный алфавит А (4,0-6,1) / линейный алфавит В (7,0-9,2) / футарк (9,5-10,2) / каракан (10,5-)
Node.js - V8

2. Каковы основные компоненты браузера?

  1. "Пользовательский интерфейс"- Включает адресную строку, кнопки вперед/назад, меню закладок и многое другое.
  2. "браузерный движок"- Передача инструкций между пользовательским интерфейсом и механизмом рендеринга.
  3. "движок рендеринга"- Отвечает за отображение запрошенного контента. Если запрошенный контент представляет собой HTML, он отвечает за синтаксический анализ содержимого HTML и CSS и отображение проанализированного содержимого на экране.
  4. "Интернет"- Для сетевых вызовов, таких как HTTP-запросы.
  5. "Серверная часть пользовательского интерфейса"- Для рисования основных виджетов, таких как поля со списком и окна.
  6. "Переводчик JavaScript"- Для разбора и выполнения кода JavaScript.
  7. "хранилище данных"- Это слой сохранения. Браузер должен сохранять на жестком диске различные данные, например файлы cookie. Новая спецификация HTML (HTML5) определяет «веб-базу данных», полную (но облегченную) базу данных в браузере.

Стоит отметить, что, в отличие от большинства браузеров, Chrome Browser, каждая вкладка соответствует каждому экземпляру двигателя рендеринга. Каждая вкладка является отдельным процессом.


3. Почему JavaScript однопоточная, это конфликтует с async?

Дополнение: В JS нет концепции потоков, а так называемый одиночный поток относится только к многопоточности. Первоначальный дизайн JS не учитывал их.Из-за функции JS, которая не имеет параллельной обработки задач, мы называем ее «один поток».

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

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

Проверьте код 👇

function foo() {
    console.log("first");
    setTimeout(( function(){
        console.log( 'second' );
    }),5);
}
 
for (var i = 0; i < 1000000; i++) {
    foo();
}

Результат печати состоит в том, что сначала много первых, а затем вторых.

Асинхронный механизм завершается двумя или более резидентными потоками браузера.Например, асинхронный запрос выполняется двумя резидентными потоками, потоком выполнения JS и потоком триггера события.

  • Поток выполнения JS инициирует асинхронный запрос (браузер откроет поток HTTP-запроса для выполнения запроса. В это время задача JS завершена, а оставшиеся задачи в очереди потока будут продолжать выполняться)
  • Затем в какой-то момент в будущем поток, запускаемый событием, отслеживает выполнение ранее инициированного HTTP-запроса, вставляет событие завершения в конец очереди выполнения JS и ждет, пока JS его обработает.

Другой пример: триггеры таймера (settimeout и setinterval) запускаются"Поток таймера браузера"Счетчик времени выполнения, а затем вставьте запрос на выполнение функции обработки времени в конец очереди выполнения JS в момент времени (поэтому при использовании этих двух функций фактическое время выполнения больше или равно указанному время, и точное время не гарантируется).

Так сказать, однопоточный и асинхронный JS — это скорее поведение браузера, и между ними нет конфликта.


4. Будет ли загрузка CSS вызывать блокировку?

Вывод первый

  • CSSне блокируетDOMразбирает, но блокируетDOMоказывать.
  • CSSБудет блокировать выполнение JS и не будет блокировать загрузку файла JS.

Поговорим о роли CSSOM

  • Во-первых, это возможность предоставить JavaScript возможность манипулировать таблицами стилей.
  • Во-вторых, предоставить базовую информацию о стиле для композиции дерева макета.
  • Этот CSSOM отображается в DOM как document.styleSheets.

Из процесса рендеринга в браузере, о котором мы говорили ранее, мы видим, что:

DOM и CSSOM обычно строятся параллельно, поэтому"Загрузка CSS не блокирует синтаксический анализ DOM".

Однако, поскольку дерево рендеринга зависит от дерева DOM и дерева CSSOM, оно должно дождаться загрузки обоих и завершить соответствующее построение перед рендерингом."Загрузка CSS блокирует рендеринг DOM".

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

Поэтому, чтобы предотвратить непредсказуемые результаты рендеринга, настройки браузера"Поток рендеринга GUI и механизм JavaScript являются взаимоисключающими."Отношение.

Следует отметить следующее:

"Иногда JS нужно дождаться загрузки CSS, почему так?"

Подумайте хорошенько, на самом деле это имеет смысл делать, если содержимое скрипта получить стиль элемента, ширину и т.д.CSSСвойства элемента управления, которые браузер должен вычислить, т. е. зависит отCSS. Браузер не может понять, что такое содержимое скрипта, и, чтобы избежать приобретения стилей, он должен дождаться загрузки всех предыдущих стилей перед его выполнением.JS.

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

Следовательно, таблица стилей выполнит выполнение до того, как будет выполнен следующий JS, поэтому"css заблокирует выполнение последующих js".


5. Почему JS блокирует загрузку страницы

Заключение Первое 👇.

  • "JS блокирует парсинг DOM", также заблокирует страницу

Вот почему файл JS помещается внизу, так почему же он блокирует синтаксический анализ DOM?

Вы можете понять это так:

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

Поэтому, чтобы предотвратить непредсказуемые результаты рендеринга, настройки браузера"Поток рендеринга GUI и механизм JavaScript являются взаимоисключающими."Отношение.

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

Когда браузер выполняет программу JavaScript, поток рендеринга GUI будет сохранен в очереди и не будет продолжаться, пока выполнение программы JS не будет завершено.

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

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


6. В чем разница между отсрочкой и асинхронностью?

  • Оба являются асинхронными для загрузки внешних файлов JS без блокировки анализа DOM.
  • Асинхронный выполняется после загрузки внешнего JS, когда браузер бездействует и до того, как запускается событие Load. Сценарии, помеченные как асинхронные, не гарантируют выполнение в том порядке, в котором они указаны. Это свойство не влияет на встроенные скрипты (то есть нет"src"сценарий свойств).
  • После отложенного после загрузки JS весь документ анализируется, триггерDOMContentLoadedВыполняется перед событием, если отсутствуетsrcсвойство (т. е. встроенный скрипт), которое не следует использовать, поскольку в данном случае оно не работает.

7. В чем разница между DOMContentLoaded и load?

  • Когда запускается событие DOMContentLoaded: только после завершения синтаксического анализа DOM, исключая такие ресурсы, как таблицы стилей и изображения.
  • Когда запускается событие onload, все DOM, таблицы стилей, скрипты, изображения и другие ресурсы на странице уже загружены.

Тогда то есть DOMContentLoaded -> сначала загрузите, затем в Jquery используйте(document).load(callback) прослушивает событие загрузки.

Затем мы можем поговорить о разнице между ними и асинхронностью и отсрочкой.

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

  • Случай 1: когда HTML не был проанализирован, был загружен асинхронный скрипт, затем HTML прекращает анализ и выполняет скрипт.После выполнения скрипта запускается событие DOMContentLoaded
  • Случай 2: после синтаксического анализа HTML загружается асинхронный скрипт, а затем выполняется скрипт, а затем запускается событие DOMContentLoaded, когда HTML анализируется, а асинхронный скрипт не загружен.

Если тег script содержит defer, то этот фрагмент скрипта не повлияет на синтаксический анализ HTML-документа, но не будет выполняться до тех пор, пока не будет завершен синтаксический анализ HTML. И DOMContentLoaded будет запущен только после завершения выполнения сценария отсрочки.

  • Случай 1. Сценарий отсрочки был загружен, когда HTML-код еще не проанализирован, и перед выполнением скрипт отсрочки будет ожидать синтаксического анализа HTML. Событие DOMContentLoaded запускается после выполнения сценария отсрочки.
  • Случай 2: Когда синтаксический анализ HTML завершен, сценарий отложенного запуска не был загружен, тогда сценарий отложенного просмотра продолжает загружаться и выполняется сразу после завершения загрузки, а событие DOMContentLoaded запускается после завершения выполнения.

8. Почему CSS-анимация более эффективна, чем JavaScript

Я думаю, что эта тема может не работать. Если вы это понимаете, вы знаете, что изменение будет только методом оптимизации. Использование JS для изменения преобразования также может использовать изменения, внесенные этим атрибутом, поэтому это утверждение немного отличается. OK.

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

Избегайте перестановки и перерисовки, насколько это возможно. Каковы конкретные операции? Если вам нужно использовать JS для достижения анимации, каковы методы оптимизации?

Например 👇

  • использоватьcreateDocumentFragmentМассовые манипуляции с DOM
  • Обработка против сотрясения/дросселирования для изменения размера, прокрутки и т. д.
  • оптимизация rAF и многое другое

Остальное я оставлю на ваше усмотрение, надеюсь, я просто собираю кусочек пазла (●'◡'●)


9. Можно ли обеспечить защиту от сотрясений и дросселирование событий?

функция дроссельной заслонки

Регулирование означает, что функция выполняется умеренно, а не запускается без модерации и выполняется один раз. Что такое модерация? Он выполняется только один раз за период времени.

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

Возьмите ключевой момент: время исполнения. Чтобы контролировать время выполнения, мы можем передать"переключатель", в комплекте с таймером setTimeout.

  function throttle(fn, delay) {
            let flag = true,
                timer = null;
            return function (...args) {
                let context = this;
                if (!flag) return;
                flag = false;
                clearTimeout(timer)
                timer = setTimeout(() => {
                    fn.apply(context, args);
                    flag = true;
                }, delay);
            };
        };

Функция debounce (дебаунс)

Обратный вызов выполняется через n секунд после запуска события, и если он снова запускается в течение этих n секунд, таймер переустанавливается.

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

Код:

  function debounce(fn, delay) {
            let timer = null
            return function (...args) {
                let context = this
                if(timer)   clearTimeout(timer)
                timer = setTimeout(function() {
                    fn.apply(context, args)
                },delay)
            }
        }

Как использовать дебаунс и дроссель и распространенные ловушки

Каким заманчивым может показаться создание колеса для подавления дребезга / газа самостоятельно или просто копирование его из случайного сообщения в блоге."Я бы рекомендовал использовать подчеркивание или Lodash напрямую". Если только нужно_.debounceа также_.throttleметод, вы можете использовать специальный инструмент сборки Lodash для создания сжатой библиотеки размером 2 КБ. Просто используйте следующую простую команду:

npm i -g lodash-cli
npm i -g lodash-clilodash-cli include=debounce,throttle

Обыкновенная яма в том, что ее называют не раз_.debounceметод:

// 错误
$(window).on('scroll', function() {
   _.debounce(doSomething, 300); 
});
// 正确
$(window).on('scroll', _.debounce(doSomething, 200));

После сохранения метода debounce в переменной можно использовать его закрытый метод.debounced_version.cancel(), lodash и underscore.js работают.

let debounced_version = _.debounce(doSomething, 200);

$(window).on('scroll', debounced_version);


// 如果需要的话debounced_version.cancel();

Подходит для сценариев применения

Стабилизатор

  • Поиск, когда пользователь постоянно вводит значения, используйте анти-встряску для сохранения запросов Ajax, то есть событий поля ввода.
  • Когда окно инициирует изменение размера, постоянное изменение размера окна браузера будет вызывать это событие постоянно, а использование защиты от сотрясений заставит его запускаться только один раз.

дросселирование

  • События щелчка мышью, такие как mousedown, запускаются только один раз.
  • Слушайте события прокрутки, например, нужно ли скользить вниз, чтобы автоматически загрузить больше, использовать дроссель, чтобы судить
  • Например, частота стрельбы пулями в игре (один выстрел в секунду)

10. Расскажите о своем понимании requestAnimationFrame (rAF)

Это происходит, чтобы быть связанным с дросселированием и имеет некоторые сходства, поэтому я собираюсь разобраться на этой точке знаний.

"Что такое высокопроизводительная анимация и как она оценивается?"

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

Другими словами, каждый кадр должен рендериться за 16,7 мс (16,7 = 1000/60).

Давайте посмотрим на объяснение MDN по этому поводу👇

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

Когда мы вызываем эту функцию, мы говорим ей сделать две вещи:

  1. Нам нужна новая рама;
  2. Когда вы визуализируете новый кадр, вам нужно выполнить функцию обратного вызова, которую я вам передал

rAF по сравнению с setTimeout

Самым большим преимуществом rAF(requestAnimationFrame) является"Система сама решает, когда будет выполняться функция обратного вызова.".

В частности, система будет активно вызывать функцию обратного вызова в rAF перед каждым отрисовкой.Если частота отрисовки системы составляет 60 Гц, функция обратного вызова будет выполняться каждые 16,7 мс. Если частота отрисовки составляет 75 Гц, то этот интервал становится равным 1000/75=13,3. РС.

Другими словами, темп выполнения rAF соответствует частоте отрисовки системы. Это может гарантировать, что функция обратного вызова будет выполняться только один раз в каждом интервале отрисовки экрана (предыдущая точка знаний только что была отсортирована."Функция дросселирования"), так что это не приведет к пропуску кадров или зависанию анимации.

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

По сравнению с анимацией setTimeout она имеет следующие преимущества.

  • Когда страница скрыта или свернута, setTimeout все еще выполняет анимацию в фоновом режиме, в это время страница невидима или недоступна, а обновление анимации бессмысленно, что является пустой тратой ресурсов процессора.
  • rAF отличается. Когда страница обрабатывается в неактивном состоянии, задача рисования экрана страницы также будет приостановлена ​​системой, поэтому rAF, который следует за системой, также прекратит рендеринг. Когда страница активирована, анимация будет начать с последней остановки Локальное выполнение продолжается, что эффективно снижает нагрузку на ЦП.

когда звонить

Спецификация, кажется, определяет это следующим образом:

  • Вызывается перед повторным рендерингом.
  • Скорее всего не будет вызываться после задачи макроса

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

rAFДает вам последний шанс изменить свойства DOM до того, как браузер решит выполнить рендеринг, а затем быстро отобразит его для вас при следующем рендеринге, поэтому это идеальный выбор для плавной анимации.

Что касается макрозадач и микрозадач, то можно сказать, что нам нужно расширять пространство, и мы пока не будем здесь их разбирать.

rAF по сравнению с дросселированием

а также_.throttle(dosomething, 16)эквивалентность. Это высокая точность, и если вам нужна более высокая точность, вы можете использовать собственный API браузера.

Дроссельный метод можно заменить на rAF API, рассмотрим плюсы и минусы:

преимущество

  • Анимация поддерживается со скоростью 60 кадров в секунду (16 мс на кадр), браузер самостоятельно определяет лучшее время для рендеринга.
  • Простой и стандартный API, низкая стоимость обслуживания в дальнейшем

недостаток

  • Запуск/отмена анимации должен контролироваться разработчиком, в отличие от «.debounce» или «.throttle», которые обрабатываются внутри функций.
  • Ничего не будет выполняться, когда вкладка браузера не активна.
  • Хотя все современные браузерыОба поддерживают RAF, IE9, Opera Mini и старые версии Android по-прежнемунужно исправлять.
  • Node.js не поддерживает и не может использоваться на стороне сервера для событий файловой системы.

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

Когда дело доходит до запросов AJAX, добавления/удаления классов (которые могут запускать анимацию CSS), я бы выбрал_.debounceили_.throttle, вы можете установить более низкую частоту выполнения (200 мс в примере заменены на 16 мс).


11. Можно ли реализовать ленивую загрузку изображений?

页可见区域宽: document.body.clientWidth;
网页可见区域高: document.body.clientHeight;
网页可见区域宽: document.body.offsetWidth (包括边线的宽);
网页可见区域高: document.body.offsetHeight (包括边线的宽);
网页正文全文宽: document.body.scrollWidth;
网页正文全文高: document.body.scrollHeight;
网页被卷去的高: document.body.scrollTop;
网页被卷去的左: document.body.scrollLeft;
网页正文部分上: window.screenTop;
网页正文部分左: window.screenLeft;
屏幕分辨率的高: window.screen.height;
屏幕分辨率的宽: window.screen.width;
屏幕可用工作区高度: window.screen.availHeight;

Об использовании scrollTop, offsetTop, scrollLeft, offsetLeft,кликните сюда

"Принципиальные идеи"

  1. получить все фотографииimg dom
  2. Основное внимание уделяется второму шагу, чтобы определить, находится ли текущее изображение в видимой области.
  3. После достижения высоты видимой области установите для атрибута data-src img значение src.
  4. привязать окноscrollмероприятие

Конечно, для лучшего взаимодействия с пользователем по умолчанию"карта-заполнитель"

Этот тестовый код

CSS-код👇

<style>
        img{
            display: block;
            height: 320px;
            margin-top: 20px;
            margin: 10px auto;
        }
</style>

HTML👇

<img src="default.png" data-src="https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1595328889118&di=1665d7e122bc96be92d0f3e1b2f5e302&imgtype=0&src=http%3A%2F%2Fwork.361ser.com%2FContent%2Fueditor%2Fnet%2Fupload%2Fimage%2F20171014%2F6364359407281350179759303.jpg" />

первый способ

"clientHeight-scrollTop-offsetTop"

Перейти непосредственно к коду, который я запускаю👇

let Img = document.getElementsByTagName("img"),
            len = Img.length,
            count = 0; 
        function lazyLoad () {
            let viewH = document.body.clientHeight, //可见区域高度
                scrollTop = document.body.scrollTop; //滚动条距离顶部高度
            for(let i = count; i < len; i++) {
                if(Img[i].offsetTop < scrollTop + viewH ){
                    if(Img[i].getAttribute('src') === 'default.png'){
                        Img[i].src = Img[i].getAttribute('data-src')
                        count++;
                    }
                }
            }
        }
        function throttle(fn, delay) {
            let flag = true,
                timer = null;
            return function (...args) {
                let context = this;
                if (!flag) return;
                flag = false;
                clearTimeout(timer)
                timer = setTimeout(() => {
                    fn.apply(context, args);
                    flag = true;
                }, delay);
            };
        };
        window.addEventListener('scroll', throttle(lazyLoad,1000))
        
        lazyLoad();  // 首次加载

второй способ

использоватьelement.getBoundingClientRect()API получает максимальное значение напрямую.

код👇

let Img = document.getElementsByTagName("img"),
            len = Img.length,
            count = 0; 
        function lazyLoad () {
            let viewH = document.body.clientHeight, //可见区域高度
                scrollTop = document.body.scrollTop; //滚动条距离顶部高度
            for(let i = count; i < len; i++) {
                if(Img[i].getBoundingClientRect().top < scrollTop + viewH ){
                    if(Img[i].getAttribute('src') === 'default.png'){
                        Img[i].src = Img[i].getAttribute('data-src')
                        count++;
                    }
                }
            }
        }
        function throttle(fn, delay) {
            let flag = true,
                timer = null;
            return function (...args) {
                let context = this;
                if (!flag) return;
                flag = false;
                clearTimeout(timer)
                timer = setTimeout(() => {
                    fn.apply(context, args);
                    flag = true;
                }, delay);
            };
        };
        window.addEventListener('scroll', throttle(lazyLoad,1000))

        lazyLoad();  // 首次加载 

Кажется, похоже, я не знаю, что-то не так с тем, как я это написал (●'◡'●), похоже

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

图片懒加载
Ленивая загрузка изображения

12. Расскажите мне о вашем файле Cookie LocalStorage SessionStorage

Cookie

должен сорватьHTTP是一个无状态的协议, здесь в основном относится к версии HTTP1.x.Просто можно понять, что даже если один и тот же клиент отправляет запросы на сервер два раза подряд, сервер не может распознать запрос, отправленный одним и тем же клиентом, вызывая проблемы, такие как в реальная жизнь, вы добавляете товар в корзину, но так как тот же клиент не может быть распознан, если вы обновите страницу, он будет 🤭

Чтобы решить проблему, вызванную отсутствием состояния HTTP (HTTP1.x), файлы cookie появились позже.

Существование файлов cookie не для решения проблемы отсутствия состояния протокола связи, а для решения проблемы состояния сеанса между клиентом и сервером.Это состояние относится к состоянию серверной службы, а не к состоянию протокол связи.

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

Настройки файлов cookie

Как это настроить? Проще говоря 👇

  1. Клиент отправляет HTTP-запрос на сервер
  2. Когда сервер получает HTTP-запрос, добавьте поле Set-Cookie в заголовок ответа.
  3. Браузер сохраняет куки после получения ответа
  4. После этого информация о файлах cookie отправляется на сервер через поле Cookie в каждом запросе к серверу.

Директива о файлах cookie

На картинке ниже мы можем видеть некоторые свойства, связанные с файлами cookie👇.

Cookie
Cookie

Вот несколько моментов, которые вы могли не заметить:

"Name/Value"

При работе с файлами cookie с помощью JavaScript обратите внимание на кодировку значения.

Expires/Max-Age

Expires используется для установки времени истечения срока действия файла cookie. Например:

Set-Cookie: id=aad3fWa; Expires=Wed, 21 May 2020 07:28:00 GMT;
  • Когда атрибут Expires по умолчанию использует файл cookie сеанса.
  • Как показано на рисунке выше, значением Expires является Session, что означает файлы cookie сеанса.
  • В случае сеансовых файлов cookie значение сохраняется в памяти клиента и истекает, когда пользователь закрывает браузер.
  • Следует отметить, что в некоторых браузерах предусмотрена функция восстановления сеанса, при закрытии браузера файлы cookie сеанса сохраняются.
  • В отличие от сеансовых файлов cookie, постоянные файлы cookie хранятся на жестком диске пользователя до истечения срока их действия или пока файл cookie не будет очищен.

Max-Age используется для установки количества секунд, которые должны пройти до истечения срока действия файла cookie. Например:

Set-Cookie: id=a3fWa; Max-Age=604800;

Если существуют и Expires, и Max-Age, Max-Age имеет приоритет.

Domain

Домен указывает имя хоста, на который могут быть отправлены файлы cookie. Если не указано, по умолчанию используется хост-часть текущего адреса доступа к документу (но не поддомен).

Обратите внимание, что файлы cookie не могут быть установлены для разных доменов.

Path

Путь указывает URL-адрес, который должен появиться в пути к запрошенному ресурсу, прежде чем можно будет отправить заголовок Cookie. например, установкаPath=/docs,/docs/Web/Ресурсы ниже будут иметь заголовок Cookie,/testЗаголовок Cookie не переносится.

"Идентификаторы домена и пути вместе определяют область действия файла cookie: то есть, на какие URL-адреса должен быть отправлен файл cookie."

Безопасное имущество

Файлы cookie, помеченные как безопасные, должны отправляться на сервер только через запросы, зашифрованные протоколом HTTPS. Используя протокол безопасности HTTPS, файлы cookie можно защитить от кражи и подделки в процессе передачи между браузером и веб-сервером.

HTTPOnly

Установка атрибута HTTPOnly предотвращает доступ скриптов на стороне клиента к файлам cookie через document.cookie и т. д., помогая избежать XSS-атак.

SameSite

Атрибут SameSite предотвращает атаки с подделкой межсайтовых запросов (CSRF), предотвращая отправку файлов cookie во время межсайтовых запросов.

Атака CSRF будет обсуждаться позже, здесь.

Каково влияние этого изменения значения свойства?

Samesite
Samesite

Как видно из приведенного выше рисунка, для большинства веб-приложений четыре случая формы сообщения, iframe, AJAX и изображения изменились с отправки сторонних файлов cookie между сайтами на их отсутствие.

Роль файлов cookie

Файлы cookie в основном используются для следующих трех аспектов:

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

Недостатки файлов cookie

От размера, безопасности, увеличения размера запроса.

  • Дефект емкости. Предельный размер файлов cookie составляет всего4KB, может использоваться только для хранения небольшого количества информации.
  • Чтобы снизить производительность, файл cookie следует за именем домена. Независимо от того, нужен ли файл cookie для адреса под доменным именем, запрос принесет полный файл cookie. Увеличение количества запросов приведет к огромным потерям.
  • Недостаток безопасности заключается в том, что файлы cookie передаются в браузере и на сервере в виде простого текста, который может быть легко получен нелегальными пользователями.Если значение HTTPOnly равно false, информация о файлах cookie также может быть напрямую прочитана через JS-скрипты.

локальное хранилище и хранилище сессий

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

По стандарту HTML 5 для нас появились localStorage и sessionStorage.

Сходства и различия

Классификация Жизненный цикл место хранения место хранения
cookie Он хранится в памяти по умолчанию и истечет при закрытии браузера (если установлено время истечения, он истечет после истечения времени) 4KB Сохраняется на стороне клиента, будет приноситься с каждым запросом
localStorage Теоретически, он действителен постоянно, если только активно не очищается. 4,98 МБ (разные браузеры, сафари 2,49 МБ) Хранится на стороне клиента и не взаимодействует со стороной сервера. Экономьте сетевой трафик
sessionStorage Действителен только для текущего веб-сеанса и будет очищен после закрытия страницы или браузера. 4,98 МБ (в некоторых браузерах нет ограничений) То же

Метод работы

Далее посмотрим как это сделатьlocalStorageа такжеsessionStorage

let obj = { name: "TianTianUp", age: 18 };
localStorage.setItem("name", "TianTianUp"); 
localStorage.setItem("info", JSON.stringify(obj));

Тогда вы сможете получить соответствующее значение при вводе того же доменного имени👇

let name = localStorage.getItem("name");
let info = JSON.parse(localStorage.getItem("info"));

Отсюда видно, чтоlocalStorageНа самом деле все строки сохраняются, если это объект хранения, то нужно вызватьJSONизstringifyметод и использованиеJSON.parseдля разбора на объекты.

Сценарии применения

  • localStorage для данных постоянного кеша, таких как настройки конфигурации страницы по умолчанию, такие как официальный сайтlogo,место храненияBase64Ресурсы форматирования изображений и т.д.;
  • sessionStorage подходит для одноразового временного хранения данных, хранения текущих записей информации о просмотре, так что, если подстраница закрыта, эти записи не нужны, и информация формы сохраняется, так что, если подстраница обновляется , информация формы не будет потеряна.

13. Расскажите о кешировании браузера

Браузерное кэширование — важное средство оптимизации производительности, а также очень важное для понимания механизма кэширования.Давайте разбираться👇

Сильный кеш

Сильное кэширование двух связанных полей,"Expires","Cache-Control".

"Сильный кеш разделен на два случая, один для отправки HTTP-запросов, а другой не нужно отправлять."

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

  • Версия HTTP1.0 с использованием Expires, HTTP1.1 с использованием Cache-Control

Expires

ExpiresТо есть время истечения, которое относительно времени сервера и существует в заголовке ответа, возвращаемом сервером.До истечения срока данные можно получить напрямую из кеша без повторного запроса. Например следующее:

Expires:Mon, 29 Jun 2020 11:10:23 GMT

Указывает, что этот ресурс доступен в 2020 году.7月29日11:10:23Когда он истечет, запрос будет повторно инициирован на сервер, когда он истечет.

С этим подходом есть проблема:"Время сервера и время браузера могут не совпадать", поэтому HTTP1.1 предлагает вместо него новое поле.

Cache-Control

В версии HTTP 1.1 используется это поле Время, используемое в этом поле, является временем истечения срока действия, которое соответствует max-age.

Cache-Control:max-age=6000

Вышеизложенное означает, что через 6000 секунд после возврата ресурса кеш можно использовать напрямую.

Конечно, в ней много других ключевых инструкций, и я разобрала несколько важных👇

будь осторожен:

  • Когда Expires и Cache-Control существуют одновременно, Cache-Control имеет приоритет.
  • Конечно, когда ресурс кеша недействителен, то есть сильный кеш не попал, то входим в кеш согласования👇

Согласовать кеш

После того, как сильный кеш недействителен, браузер переносит ответ缓存TagЧтобы отправить запрос на сервер, сервер решает, использовать ли кеш согласно соответствующему тегу.

Существует два типа кэша:"Last-Modified"а также"ETag". У обоих есть свои преимущества, и нет такого понятия, как одно над другим.绝对的优势, который отличается от сильного кеша двумя упомянутыми выше тегами.

Last-Modified

Это поле представляет"Последнее изменение". После того, как браузер отправит запрос на сервер в первый раз, сервер добавит это поле в заголовок ответа.

После того, как браузер получит его,"Если запросить повторно", будет перенесено в заголовок запросаIf-Modified-SinceПоле, значение этого поля — время последней модификации, отправленное сервером.

Сервер получает заголовок запросаIf-Modified-SinceПосле поля оно фактически будет соответствовать该资源的最后修改时间В сравнении:

  • Если это значение в заголовке запроса меньше, чем время последнего изменения, пришло время обновить. Возврат нового ресурса аналогичен обычному процессу ответа на HTTP-запрос.
  • В противном случае верните 304, указав браузеру использовать кеш напрямую.

ETag

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

Когда браузер получает значение ETag, он будет использовать это значение в качестве следующего запроса."If-None-Match"Содержимое этого поля отправляется на сервер.

сервер получает"If-None-Match"После этого он будет следить за ресурсом на сервере"ETag"Сравните 👇

  • Если они одинаковы, возвращайте 304 напрямую, сообщая браузеру, что нужно использовать кеш напрямую.
  • Если он отличается, это означает, что содержимое было обновлено и возвращен новый ресурс, что соответствует обычному процессу ответа на HTTP-запрос.

Сравните два

  • представление,Last-Modifiedлучше чемETag,Last-ModifiedМоменты времени записываются иEtagСоответствующее хэш-значение должно быть сгенерировано в соответствии с алгоритмом MD5 файла.
  • точность,ETagлучше чемLast-Modified.ETagМаркируйте ресурсы в соответствии с их содержимым, чтобы можно было точно отслеживать изменения ресурсов.Last-ModifiedВ некоторых сценах невозможно точно уловить изменения, например👇
    • Файл ресурсов отредактирован, но содержимое файла не изменилось, что также приведет к аннулированию кеша.
    • Единицей времени, которую может воспринимать Last-Modified, являются секунды.Если файл изменяется несколько раз в течение 1 секунды, то Last-Modified в это время не отражает модификацию.

наконец,"Если оба метода поддерживаются, сервер отдаст приоритетETag".

расположение кеша

Далее, если мы рассмотрим использование кеша, где находится кеш?

Расположение кеша браузера можно разделить на четыре типа, приоритет выстроен от высокого к низкому👇

  • Service Worker
  • Memory Cache
  • Disk Cache
  • Push Cache

Service Worker

Этот сценарий приложения, такой как PWA, основан на идее Web Worker.Поскольку он отделен от формы браузера, он не может получить прямой доступ к DOM. Он может выполнять такие функции, как:离线缓存,消息推送а также网络代理离线缓存то есть"Service Worker Cache".

Memory Cache

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

Disk Cache

Кэш, хранящийся на диске, медленнее, чем кеш памяти, с точки зрения эффективности доступа, а его преимущества заключаются в емкости и продолжительности хранения.

Disk Cache VS Memory Cache

Сравнение двух, основная стратегия👇

Если скорость использования контента высока, файл сначала попадет на диск

Файлы JS и CSS большего размера будут размещены непосредственно на диске и наоборот.

Push Cache

Push cache, это последняя линия защиты в браузере, этоHTTP/2Содержание. Я не знаю подробностей, но вы можете узнать, если вам интересно.

Суммировать

  • Сначала проверьтеCache-Control, попробуйте, чтобы узнать, доступен ли сильный кеш
  • Если доступно, используйте напрямую
  • В противном случае войдите в кеш согласования, отправьте HTTP-запрос, и сервер передастIf-Modified-SinceилиIf-None-MatchПоле для проверки обновления ресурса
  • Обновление ресурса, возврат ресурса и код состояния 200.
  • В противном случае вернитесь к 304 и прямо сообщите браузеру, чтобы он сразу переходил к ресурсу из кеша.

14. Подскажите, что произошло от ввода URL до отрисовки страницы?

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

Итак, давайте начнем, если ваш вклад 👇

https://juejin.cn

👇👇👇

сетевой запрос

1. Создайте запрос

Во-первых, браузер строит"строка запроса"информация (показана ниже), после построения браузер готов инициировать сетевой запрос👇

GET / HTTP1.1
GET是请求方法,路径就是根路径,HTTP协议版本1.1

2. Кэш поиска

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

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

3. DNS-разрешение

Если вы вводите доменное имя, нам нужно получить соответствующее доменное имя.ip地址.这个过程需要依赖一个服务系统,叫做是DNS域名解析, процесс от поиска до получения конкретного IP называетсяDNS解析.

Что касается статей DNS, вы можете увидетьБлог Руан Ифэн

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

"Процесс разрешения резюмируется следующим образом"👇

  1. "Сначала проверьте, есть ли кеш соответствующего доменного имени, и если да, используйте кешированный IP-адрес для прямого доступа к нему."

    1. ipconfig /displaydns
      // 输入这个命令就可以查看对应的电脑中是否有缓存
      
  2. "Если нет в кеше, идем в файл hosts"обычно вc:\windows\system32\drivers\etc\hosts

  3. Если доменное имя, которое вы хотите разрешить, не найдено в файле hosts, оно будет"Доменное имя отправляется на DNS-сервер, настроенный вами",Также известен как"Локальный DNS-сервер".

    1. ipconfig/all
      通过这个命令可以查看自己的本地dns服务器
      
  4. если"На локальном DNS-сервере есть запись о соответствующем доменном имени", запись возвращается.

    1. DNS-сервер компьютера обычно предоставляется крупными операторами, такими как China Unicom, или предоставляется известными поставщиками услуг DNS, такими как 180.76.76.76, 223.5.5.5, 4 114 и т. д. Он кэширует большое количество IP-адресов общих доменные имена, такие распространенные Веб-сайт задокументирован. Нет необходимости искать корневой сервер.

  5. Если на собственном сервере компьютера нет записи, она перейдет на корневой сервер. В мире всего 13 групп корневых серверов, вернитесь и найдите одну из них, найдя корневой сервер,"Корневой сервер вернет соответствующий «сервер доменных имен верхнего уровня» в соответствии с запрошенным доменным именем.",Такие как:

    1. Если запрашиваемое доменное имяxxx.com, возвращается сервер, отвечающий за домен com
    2. еслиxxx.cn, он отправляется на сервер, отвечающий за домен cn
    3. еслиxxx.ca, он отправляется на сервер, отвечающий за домен ca
  6. "Когда сервер домена верхнего уровня получит запрос, он вернет адрес сервера домена второго уровня."

    1. Например, URL-адресwww.xxx.edu.cn, то сервер доменных имен верхнего уровня перенаправляет его ответственному.edu.cnДополнительный сервер для домена
  7. "По аналогии, он в конечном итоге будет отправлен на самый точный dns, отвечающий за блокировку и запрос доменного имени, и можно будет получить результат запроса."

  8. последний шаг,"Локальный DNS-сервер, возвращающий окончательное разрешение, возвращающийся к клиенту, разговаривающий с клиентом, просто вопрос одного, клиент не знает, что локальный DNS-сервер прошел тысячи вод."

Выше приведен общий процесс, если вам интересно, можете посмотреть подробнее.

установить TCP-соединение

Мы знаем, что 👉Chrome требует не более 6 TCP-подключений одновременно под одним и тем же доменным именем. Если их больше 6, остальные запросы должны ждать.

Затем считаем, что ждать не нужно, и входим в фазу установления TCP-соединения.

УчреждатьTCP连接Пройдите следующие три стадии:

  • пройти через"трехстороннее рукопожатие"Установите соединение между клиентом и сервером.
  • Передача данных.
  • Отключенная фаза. Передача данных завершена, теперь пора отключиться, через"помахал четыре раза"отключить.

Из вышеизложенного видно, какие средства использует TCP-соединение для обеспечения надежности передачи данных.三次握手Подтвердить подключение, второе数据包校验Убедитесь, что данные прибывают на приемную сторону, на три四次挥手Отключить.

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

отправить HTTP-запрос

После завершения TCP-соединения следующим шагом является связь с сервером, которую мы часто называем отправкой HTTP-запросов.

Чтобы отправить HTTP-запрос, вам нужно иметь три вещи:"строка запроса","заголовок запроса","тело запроса".

Давайте посмотрим, как это выглядит 👇

Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3
Accept-Encoding: gzip, deflate, br
Accept-Language: zh-CN,zh;q=0.9
Cache-Control: no-cache
Connection: keep-alive
Cookie: /* 省略cookie信息 */
Host: juejin.im
Pragma: no-cache
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/84.0.4147.89 Safari/537.36

Последним является тело запроса, тело запроса можно найти только вPOSTОн существует в сценарии запроса, общий —表单提交

ответ сети

HTTP-запрос прибывает на сервере, сервер выполняет соответствующую обработку. Наконец, передайте данные в браузер, который обычно является ответ возврата, мы сказали.

Как и часть запроса, сетевой ответ состоит из трех частей:"строка ответа","заголовок ответа"а также"тело ответа".

Строка ответа выглядит так👇

HTTP/1.1 200 OK

Каковы соответствующие данные заголовка ответа? Давайте возьмем пример, чтобы увидеть 👇

Access-Control-Max-Age: 86400
Cache-control: private
Connection: close
Content-Encoding: gzip
Content-Type: text/html;charset=utf-8
Date: Wed, 22 Jul 2020 13:24:49 GMT
Vary: Accept-Encoding
Set-Cookie: ab={}; path=/; expires=Thu, 22 Jul 2021 13:24:49 GMT; secure; httponly
Transfer-Encoding: chunked

Далее получаем данные, думаете TCP соединение будет разорвано?

Этот смотрит на поле Connection в заголовке ответа. Значение вышеприведенного поля близко, то оно будет отключено.В нормальных условиях в версии HTTP1.1 заголовок запроса обычно содержит"Connection: Keep-Alive"Указывает, что установлено постоянное соединение, поэтомуTCPСоединение всегда будет поддерживаться, и ресурсы, запрашивающие единый сайт, будут повторно использовать это соединение.

Ситуация будет отключенаTCPСоединение, поток запросов-ответов завершается.

На этом сетевой запрос подошел к концу, и следующий контент — процесс рендеринга👇

этап визуализации

Дополнительные технические термины можно свести к следующим этапам:

  1. Построить DOM-дерево
  2. расчет стиля
  3. этап макета
  4. Слоистый
  5. рисовать
  6. Блокировать
  7. Растеризация
  8. синтез

Для процесса рендеринга вы можете прочитать мое предыдущее резюме ✅✅✅

[1.1W word] Читы на девушку - как работает браузер (процесс рендеринга)


15. Расскажите о своем понимании перестановки и перерисовки

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

Поленитесь, прочитайте статью ниже👇

[1.1W word] Читы на девушку - как работает браузер (процесс рендеринга)


16. Поговорите о междоменной политике, политике одного источника и междоменных решениях.

что такое кросс домен

Междоменный означает, что браузер не может выполнять скрипты с других сайтов. Это вызвано политикой браузера о том же происхождении, ограничением безопасности, которое браузеры налагают на JavaScript.

Та же политика происхождения

Такая же политика происхождения является политикой безопасности. Так называемая гомология относится к тому же протоколу, доменному имени и порту.

同源策略
Та же политика происхождения

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

Ограничьте следующее поведение:

  • Файлы cookie, LocalStorage и IndexDB не могут быть прочитаны
  • Объекты DOM и JS не могут быть получены
  • Ajax-запрос не может быть отправлен

решение

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

перекрестный домен jsonp

Используя уязвимость тегов script без междоменных ограничений, веб-страницы могут получать динамические данные JSON, сгенерированные из других источников.Конечно, запросы JSONP должны поддерживаться сервером другой стороны.

"По сравнению с АЯКС"

JSONP такой же, как AJAX, оба способа для клиента отправлять запросы на сервер и получать данные с сервера. Но AJAX относится к политике одного и того же происхождения, JSONP относится к политике другого происхождения (междоменный запрос).

"Преимущества JSONP"

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

"Идеи👇"

  • Создание тегов сценария
  • Установите атрибут src тега script, передайте параметр со знаком вопроса и установите имя обратного вызова функции обратного вызова.
  • Вставить в html текст
  • Вызов callback-функции, параметр res — полученные данные
let script = document.createElement('script');

script.src = 'http://www.baidu.cn/login?username=TianTianUp&callback=callback';

document.body.appendChild(script);

function callback(res) {
  console.log(res);
 }

Конечно, jquery также поддерживает реализацию jsonp.

  $.ajax({
            url: 'http://www.baidu.cn/login',
            type: 'GET',
            dataType: 'jsonp', //请求方式为jsonp
            jsonpCallback: 'callback',
            data: {
                "username": "Nealyang"
            }
        })

"Преимущества JSONP"

  • Он не ограничен политикой одного и того же источника, как запросы Ajax, реализованные объектом XMLHttpRequest.
  • Он более совместим, работает в старых браузерах, не требует поддержки XMLHttpRequest или ActiveX.
  • А после выполнения запроса результат можно вернуть, вызвав callback.

"Недостатки JSONP"

  • Он поддерживает только запросы GET и не поддерживает другие типы HTTP-запросов, такие как POST.
  • Он поддерживает только междоменные HTTP-запросы и не может решить проблему выполнения вызовов JavaScript между двумя страницами разных доменов.

Совместное использование ресурсов между источниками CORS

CORS (Cross-Origin Resource Sharing) совместное использование ресурсов между источниками определяет, как браузер и сервер должны взаимодействовать при доступе к ресурсам из разных источников. Основная идея CORS заключается в использовании настраиваемых заголовков HTTP, позволяющих браузеру взаимодействовать с сервером, чтобы решить, будет ли запрос или ответ успешным или нет. В настоящее время все браузеры поддерживают эту функцию, и браузер IE не может быть ниже IE10. Весь процесс связи CORS автоматически завершается браузером и не требует участия пользователя. Для разработчиков связь CORS ничем не отличается от связи AJAX того же происхождения, и код точно такой же. Как только браузер обнаружит, что запрос AJAX является перекрестным, он автоматически добавит некоторую дополнительную информацию в заголовок, а иногда будет сделан дополнительный запрос, но пользователь этого не почувствует.

Выше цитата, ключевые моменты, которые нужно помнить👇

"CORS требует поддержки как браузера, так и серверной части. IE 8 и 9 должны делать это через XDomainRequest".

  • "Браузер будет автоматически осуществлять связь CORS, а ключом к реализации связи CORS является серверная часть. Пока серверная часть реализует CORS, реализуется междоменный доступ."
  • Сервер может установить Access-Control-Allow-Origin для включения CORS. Этот атрибут указывает, какие доменные имена могут получить доступ к ресурсу. Если установлен подстановочный знак, это означает, что все веб-сайты могут получить доступ к ресурсу.

Запросы делятся на"простой запрос"а также"не простой запрос", так что мы понимаем оба случая.

"простой запрос"

Если следующие два условия выполнены, это простой запрос👇

Условие 1. Используйте один из следующих методов:

  • GET
  • HEAD
  • POST

Условие 2: значение Content-Type ограничено одним из следующих 👇

  • text/plain
  • multipart/form-data
  • application/x-www-form-urlencoded

Ни один из объектов XMLHttpRequestUpload в запросе не зарегистрировал ни одного прослушивателя событий;

Доступ к объектам XMLHttpRequestupload можно получить с помощью свойств XMLHttpRequest.upload.

"сложный запрос"

Запрос, который не соответствует вышеуказанным условиям, определенно является сложным запросом. Для запросов CORS сложных запросов перед формальным общением будет добавлен запрос HTTP-запроса, который называется предварительным запросом. Этот запрос является дополнительным методом, и этот запрос используется, чтобы узнать, разрешает ли сервер междоменные запросы.

Давайте сразу к примеру👇 Взгляните на полный сложный запрос и познакомьтесь с полями CORS-запроса.

//server2.js
let express = require('express')
let app = express()
let whitList = ['http://localhost:3000'] //设置白名单
app.use(function(req, res, next) {
  let origin = req.headers.origin
  if (whitList.includes(origin)) {
    // 设置哪个源可以访问我
    res.setHeader('Access-Control-Allow-Origin', origin)
    // 允许携带哪个头访问我
    res.setHeader('Access-Control-Allow-Headers', 'name')
    // 允许哪个方法访问我
    res.setHeader('Access-Control-Allow-Methods', 'PUT')
    // 允许携带cookie
    res.setHeader('Access-Control-Allow-Credentials', true)
    // 预检的存活时间
    res.setHeader('Access-Control-Max-Age', 6)
    // 允许返回的头
    res.setHeader('Access-Control-Expose-Headers', 'name')
    if (req.method === 'OPTIONS') {
      res.end() // OPTIONS请求不做任何处理
    }
  }
  next()
})
app.put('/getData', function(req, res) {
  console.log(req.headers)
  res.setHeader('name', 'jw') //返回一个响应头,后台需设置
  res.end('我不爱你')
})
app.get('/getData', function(req, res) {
  console.log(req.headers)
  res.end('我不爱你')
})
app.use(express.static(__dirname))
app.listen(4000)

Приведенный выше код даетсяhttp://localhost:3000/index.htmlКhttp://localhost:4000/Запросы между источниками, как мы сказали выше, серверная часть является ключом к связи CORS.

Приведенный выше пример обязательно вам поможет.За этим кодом следует浪里行舟Код приходит, а источник указан в ссылке.

"В отличие от JSONP"

  • JSONP может реализовывать только запросы GET, а CORS поддерживает все типы HTTP-запросов.
  • С помощью CORS разработчики могут использовать обычный XMLHttpRequest для отправки запросов и получения данных с лучшей обработкой ошибок, чем JSONP.
  • JSONP в основном поддерживается старыми браузерами, которые часто не поддерживают COR, в то время как большинство современных браузеров уже поддерживают CORS)

Междоменный протокол WebSocket

Websocket — это постоянный протокол HTML5, который реализует полнодуплексную связь между браузером и сервером, а также является междоменным решением.

И WebSocket, и HTTP являются протоколами прикладного уровня, оба основаны на протоколе TCP. но"WebSocket — это протокол двусторонней связи.После установления соединения как сервер WebSocket, так и клиент могут активно отправлять или получать данные друг другу.". В то же время WebSocket необходимо использовать протокол HTTP при установлении соединения, после установления соединения двусторонняя связь между клиентом и сервером не имеет ничего общего с HTTP.

Сначала рассмотрим пример👇

Локальный файл socket.html вlocalhost:3000Данные о возникновении и получение данных👇

// socket.html
<script>
    let socket = new WebSocket('ws://localhost:3000');
    socket.onopen = function () {
      socket.send('我爱你');//向服务器发送数据
    }
    socket.onmessage = function (e) {
      console.log(e.data);//接收服务器返回的数据
    }
</script>

Бэкэнд часть 👇

// server.js
let WebSocket = require('ws'); //记得安装ws
let wss = new WebSocket.Server({port:3000});
wss.on('connection',function(ws) {
  ws.on('message', function (data) {
    console.log(data);
    ws.send('我不爱你')
  });
})

Если вы хотите попробовать, рекомендуется игратьSocket.io,

  • Это связано с тем, что нативный WebSocket API не очень удобен в использовании, он хорошо инкапсулирует интерфейс webSocket
  • Предоставляет более простой и гибкий интерфейс, а также обеспечивает обратную совместимость для браузеров, не поддерживающих webSocket.

междоменный прокси nginx


17. Расскажите о своем понимании XSS-атаки

Что такое XSS-атака

Полное имя XSSCross Site Scripting, чтобы соответствоватьCSSдифференцированный, отсюда и аббревиатураXSS, что переводится как «межсайтовый скриптинг».

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

Вначале этот вид атаки осуществлялся через междоменные, поэтому он назывался «междоменный скриптинг». До сих пор существует все больше и больше способов вставки вредоносного кода в HTML-файлы, поэтому внедрение скриптов между доменами — не единственный метод внедрения, но название XSS сохранилось и по сей день.

Внедрение вредоносных скриптов может выполнить следующие действия:

  1. украсть печенье
  2. Отслеживайте поведение пользователя, например ввод пароля учетной записи и отправку его на хакерский сервер.
  3. Создание всплывающей рекламы на веб-страницах
  4. Измените DOM на фальшивую форму входа

В целом существует три способа реализации XSS-атак.

  • Сохраненная XSS-атака
  • Отраженная XSS-атака
  • XSS-атаки на основе DOM

Сохраненная XSS-атака

存储型XSS
Тип хранилища XSS

На рисунке общие шаги сохраненной XSS-атаки следующие:

  1. Во-первых, хакеры используют уязвимости сайта, чтобы отправить фрагмент вредоносного кода JavaScript в базу данных сайта;
  2. Затем пользователь запрашивает с веб-сайта страницу, содержащую вредоносный скрипт JavaScript;
  3. Когда пользователь просматривает страницу, вредоносный скрипт загружает информацию о файлах cookie пользователя и другие данные на сервер.

Например, распространенный сценарий:

Отправьте код сценария в области комментариев.Предполагая, что внешние и внутренние работы по экранированию не выполнены, контент будет загружен на сервер и будет отображаться при отображении страницы.直接执行, что эквивалентно выполнению неизвестного JS-кода. Это хранимая XSS-атака.

Отраженная XSS-атака

Отраженные XSS-атаки относятся к вредоносным скриптам как"часть сетевого запроса", а затем веб-сайт возвращает пользователю вредоносный сценарий JavaScript. Когда вредоносный сценарий JavaScript выполняется на странице пользователя, хакер может использовать его для выполнения некоторых вредоносных операций.

Например:

http://TianTianUp.com?query=<script>alert("你受到了XSS攻击")</script>

Как и выше, сервер анализирует запрос параметра после его получения и, наконец, возвращает содержимое браузеру.Браузер анализирует содержимое как часть HTML, обнаруживает, что это сценарий Javascript, и выполняет его напрямую, что подвергается атаке XSS. .

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

Главное отметить, что,"Сервер не будет хранить эти вредоносные скрипты, в чем отличие от сохраненных XSS-атак.".

XSS-атаки на основе DOM

Атаки XSS на основе DOM не затрагивают веб-сервер страницы. В частности, хакеры различными способами внедряют вредоносные скрипты на страницы пользователей и перехватывают сетевые пакеты во время передачи данных.

Общие методы угона включают в себя:

  • Взлом WIFI роутера
  • локальное вредоносное ПО

Стратегии предотвращения XSS-атак

Все описанные выше принципы XSS-атаки имеют одну общую черту: пусть вредоносные скрипты выполняются прямо в браузере.

Существует три решения для трех различных форм XSS-атак:

Фильтровать или перекодировать входные сценарии

Фильтровать или перекодировать информацию, введенную пользователем

Например👇

После перекодирования👇

&lt;script&gt;alert(&#39;你受到XSS攻击了&#39;)&lt;/script&gt;

Такой код не может быть выполнен во время парсинга html.

Конечно для<script>,<img>,<a>Могут подойти и другие теги ключевых слов, эффект такой👇

   

В конце концов, ничего не осталось

Использовать CSP

Реализация этой политики безопасности основана наContent-Security-PolicyизHTTPстолица.

может двигатьсяMDN, с более нормативным объяснением. Я просто разберусь здесь.

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

  • Ограничить загрузку файлов ресурсов в других доменах, чтобы даже если хакер вставил файл JavaScript, файл JavaScript не мог быть загружен;
  • Запретить отправку данных на сторонние домены, чтобы не произошла утечка пользовательских данных;
  • Предоставление механизма отчетности может помочь нам вовремя обнаруживать XSS-атаки.
  • Запретить выполнение встроенных скриптов и неавторизованных скриптов;

Использовать HttpOnly

Поскольку многие XSS-атаки направлены на кражу файлов cookie, мы также можем защитить наши файлы cookie с помощью атрибута HttpOnly. Таким образом, JavaScript не может прочитать значение cookie. Это также может быть хорошей защитой от XSS-атак.

Обычно сервер может установить некоторые файлы cookie в качестве флага HttpOnly. HttpOnly устанавливается сервером через заголовок ответа HTTP. Ниже приведен раздел в заголовке ответа HTTP при открытии Google:

set-cookie: NID=189=M8l6-z41asXtm2uEwcOC5oh9djkffOMhWqQrlnCtOI; expires=Sat, 18-Apr-2020 06:52:22 GMT; path=/; domain=.google.com; HttpOnly

Суммировать

XSSПод атакой понимается выполнение вредоносного скрипта в браузере с последующим получением информации пользователя для работы. в основном разделены存储型,反射型а также文档型. К профилактическим мерам относятся:

  • Фильтровать или перекодировать ввод, особенно что-то вроде<script>,<img>,<a>Этикетка
  • Использовать CSP
  • Используйте атрибут HttpOnly файлов cookie

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


18. Можете ли вы рассказать об атаке CSRF

Что такое CSRF-атака?

Полное английское название CSRF:Cross-site request forgery, поэтому это также называется «подделкой межсайтовых запросов», что означает межсайтовый запрос, инициированный хакером, чтобы побудить пользователя открыть веб-сайт хакера и использовать статус входа пользователя на веб-сайте хакера. просто говоря,"Атаки CSRF — это хакеры, которые используют статус входа пользователя в систему и совершают плохие действия через сторонние сайты."

При обычных обстоятельствах, нажмите на наводящую вас ссылку, что сделает хакер без вашего ведома?

1. Автоматически инициировать запрос на получение

Такой фрагмент кода может быть на странице хакера👇

 <img src="http://bank.example/withdraw?amount=10000&for=hacker" > 

После того, как жертва зайдет на страницу, содержащую этот img, браузер автоматическиhttp://bank.example/withdraw?account=xiaoming&amount=10000&for=hackerСделайте HTTP-запрос.

bank.exampleПолучен междоменный запрос, содержащий регистрационную информацию жертвы.

2. Автоматически инициировать POST-запрос

На странице хакера есть форма, форма автоматически отправляется👇

 <form action="http://bank.example/withdraw" method=POST>
    <input type="hidden" name="account" value="xiaoming" />
    <input type="hidden" name="amount" value="10000" />
    <input type="hidden" name="for" value="hacker" />
</form>
<script> document.forms[0].submit(); </script> 

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

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

3. Обманывайте пользователей, чтобы они нажимали на ссылки

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

 <a href="http://test.com/csrf/withdraw.php?amount=1000&for=hacker" taget="_blank">
  重磅消息!!!
  <a/>

После щелчка автоматически отправить запрос на получение, затем и自动发 GET 请求Часть того же.

Вышеуказанные три ситуации являются принципом атаки CSRF.По сравнению с XSS, атака CSRF не требует внедрения вредоносного кода в HTML, а переходит на новую страницу и использует"Уязвимость аутентификации сервера"а также"Предыдущий статус входа пользователя"для имитации действий пользователя

"Стратегия защиты"

На самом деле мы можем думать, что хакер может использовать только**cookie**Обманывает доверие сервера, но хакеры не могут его получить"cookie", тоже не видно"cookie"Содержание. Кроме того, для результатов, возвращаемых сервером, из-за браузера"Та же политика происхождения"Хакеры не могут разобрать его.

Это говорит нам о том, что объекты, которые мы хотим защитить, — это те сервисы, которые могут напрямую генерировать изменения данных, в то время как для сервисов, которые считывают данные, нам не нужно**CSRF**защита. Ключом к защите является"Поместите в запрос информацию, которую хакер не сможет подделать"

Ограничения на действия пользователей — механизм проверки кода

Метод: добавьте проверочный код, чтобы определить, активно ли пользователь инициировал запрос. Поскольку машина проверочного кода с определенной силой не может быть распознана, опасный веб-сайт не может подделать полный запрос.

1. Проверьте исходный сайт

Сайт, который проверяет источник запроса на стороне сервера.Поскольку большое количество CSRF-атак исходит от сторонних сайтов, сервер запрещает запросы от сторонних сайтов по доменам, в основном через два заголовка в заголовке HTTP-запроса.

  • Origin Header
  • Referer Header

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

Сервер может определить исходный домен запроса, проанализировав доменные имена в двух заголовках.

в,"Origin"содержит только информацию о доменном имени, а"Referer"содержит具体URL-адрес .

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

2. Используйте атрибут SameSite файла cookie.

Вы можете увидеть объяснение MDN по этому поводу

SameSiteМожно установить до трех значений,Strict,Laxа такжеNone.

  1. существуетStrictВ режиме браузер полностью запрещает сторонним запросам передавать файлы cookie. например запросsanyuan.comСайт может быть толькоsanyuan.comТолько запросы в доменном имени могут содержать файлы cookie, а запросы с других веб-сайтов не могут.
  2. существуетLaxрежиме, он немного свободнее, но только вget 方法提交表单состояние илиa 标签发送 get 请求Cookie могут быть перенесены в случае , но не в других случаях.
  3. В режиме None файлы cookie будут отправляться во всех контекстах, т. е. разрешена междоменная отправка.

3. "CSRF Token"

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

Тогда мы можем использовать Token.Без задействования XSS обычным хакерам сложно получить Token.

Вы можете прочитать эту статью, чтобы узнать, как работает Token 👉Полное понимание файлов cookie, сессий, токенов

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

Шаги токена следующие:

"Шаг 1: Вывод токена CSRF на страницу"

Прежде всего, когда пользователь открывает страницу, сервер должен сгенерировать для пользователя токен. Токен шифрует данные с помощью алгоритма шифрования. Как правило, токен включает в себя комбинацию случайной строки и метки времени. Токен нельзя помещать в куки при отправке (XSS может получить куки), иначе он будет использован злоумышленниками. Поэтому в целях безопасности лучше хранить Токен в сеансе сервера, а затем использовать JS для обхода всего дерева DOM каждый раз при загрузке страницы, и добавлять Токен после всех тегов a и form в ДОМ. Это может решить большинство запросов, но для HTML-кода, динамически генерируемого после загрузки страницы, этот метод не действует, и программисту необходимо вручную добавлять Token при написании кода.

"Шаг 2: Запрос, отправленный страницей, содержит этот токен."

Для запросов GET токен будет добавлен к адресу запроса, так что URL станетhttp://url?csrftoken=значение токена. Для запросов POST добавьте в конце формы:<input type=”hidden” name=”csrftoken” value=”tokenvalue”/>Таким образом, Токен добавляется в запрос в виде параметра.

"Шаг 3: Сервер проверяет правильность токена."

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

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

Суммировать

CSRF (подделка межсайтовых запросов), то есть подделка межсайтовых запросов, по существу нацелена на то, чтобы браузер различал, является ли запрос реальным пользователем, поэтому ключом к предотвращению является размещение информации, которая не может быть подделана хакерами. в запросе. Это не позволяет хакерам подделать полный запрос, чтобы обмануть сервер.

"Меры предосторожности": Механизм проверочного кода, проверка исходного сайта, использование атрибута SameSite файла cookie, токена CSRF.

Ссылаться на

"❤️ Всем спасибо"

Если вы считаете этот контент полезным:

  1. Поставьте лайк и поддержите его, чтобы больше людей увидело этот контент

  2. Вы можете поделиться со мной своими мыслями в области комментариев, и вы также можете записать свой мыслительный процесс в области комментариев.

  3. Если вы считаете, что это хорошо, вы также можете прочитать последние статьи TianTian (спасибо за вашу поддержку и поддержку 🌹🌹🌹):

В этой статье используетсяmdniceнабор текста