[{"data":1,"prerenderedAt":1844},["ShallowReactive",2],{"$fny7-mAHbT1uNWUXLFp9f-PYyJR-s5RrJvzHLKIcLR7k":3,"$fMMUdSFktwQFqMVGPrTtt3EC5yheBp7PzwIqznamFcMo":134,"$fc0LoAJgqXDLbKKd2JS_NpM4SuzBK8EycUXINSg09CKU":137,"$fM3ea55k6lKMPOTM84llDB26VSQDVVbxiQuSBFQw9P_c":142,"$f1Prj1xEczHja_-L7FyIGgRHd5_cSWHo7r6AE5aheAik":487,"$fI5fDmvm-5tr9wcH0eHaKZa1j3y_FQIQaHHPqbZxAHJE":708,"mdc--fczqsf-key":728,"mdc--auozyk-key":740,"mdc--wqi8nk-key":748,"mdc--wj8o7c-key":756,"mdc--vm4mo9-key":764,"mdc--g3lv0z-key":772,"mdc--80jx7f-key":842,"mdc--8roowc-key":857,"mdc-8xxk55-key":871,"mdc--s27fhi-key":879,"mdc--uttsvr-key":947,"mdc-dbcbol-key":961,"mdc--4tkjf3-key":969,"mdc--lytnv-key":1080,"mdc--yj9h8y-key":1294,"mdc-isq91l-key":1317,"mdc-yb8rba-key":1432,"mdc--x79b40-key":1448,"mdc-s1fck4-key":1629,"mdc-13jowt-key":1664,"mdc-h8cwl4-key":1742,"mdc--5guy9d-key":1750,"mdc--80cggr-key":1808,"mdc--7qyfgl-key":1836},{"content":4,"quizQuestionContent":105,"type":124,"pageMeta":125},[5,9,13,16,20,24,27,31,34,37,41,44,48,51,54,58,61,64,68,71,75,78,82,85,88,92,95,99,102],{"id":6,"value":7,"isTypeH1":8},"1947","Что такое cookie в вебе: теория, атрибуты и безопасность",true,{"id":10,"value":11,"anchor":12,"isTypeH2":8},"4514","Что такое cookie","what-is-a-cookie",{"id":14,"value":15,"isTypeParagraph":8},"10380","Cookie — это небольшой фрагмент данных (пара «имя=значение» с метаданными), который сервер просит браузер сохранить, а браузер затем автоматически отправляет обратно на сервер при последующих запросах в рамках заданной области видимости (домен, путь, контекст).\n\nКлючевая идея cookie — привязать несколько независимых HTTP-запросов к единому контексту, например к авторизованной сессии, предпочтениям интерфейса или состоянию корзины, если оно хранится на стороне сервера.",{"id":17,"description":18,"titleAlert":19,"isTypeAlertInfo":8},"683","Cookie — это не «файл» и не «база данных», а механизм HTTP-заголовков и правил хранения/отправки в браузере.",null,{"id":21,"value":22,"anchor":23,"isTypeH2":8},"4515","Как cookie передаётся по HTTP","how-cookie-is-sent-over-http",{"id":25,"value":26,"isTypeParagraph":8},"10381","Cookie устанавливается сервером через заголовок `Set-Cookie` в HTTP-ответе, а затем возвращается браузером через заголовок `Cookie` в HTTP-запросе.\n\nПример ответа сервера с установкой cookie:\n\n```\nHTTP/1.1 200 OK\nContent-Type: text/html; charset=utf-8\nSet-Cookie: session_id=abc123; Path=/; HttpOnly; Secure; SameSite=Lax; Max-Age=3600\n\n\u003Chtml>...\u003C/html>\n```\n\nПример последующего запроса браузера к тому же сайту:\n\n```\nGET /profile HTTP/1.1\nHost: example.com\nCookie: session_id=abc123\n```\n\nСхема обмена:\n\n```\n    ┌──────────┐                 ┌────────────┐\n    │ Браузер  │ 1) Запрос       │   Сервер   │\n    │          ├────────────────▶│            │\n    │          │                 │ 2) Ответ   │\n    │          │  Set-Cookie     │            │\n    │          │◀────────────────┤            │\n    │          │ 3) След. запрос │            │\n    │          │  Cookie: ...    │            │\n    └──────────┘                 └────────────┘\n```",{"id":28,"value":29,"anchor":30,"isTypeH2":8},"4516","Основные свойства и ограничения","main-properties-and-limits",{"id":32,"value":33,"isTypeParagraph":8},"10382","Cookie имеет ограниченный размер (типично около \\(4096\\) байт на одну cookie) и ограничения по количеству на домен (зависит от браузера и политики, часто десятки/сотни).\n\nCookie отправляется в каждом подходящем HTTP-запросе автоматически, поэтому увеличение размера и количества cookie повышает сетевые накладные расходы и может замедлять загрузку страниц.",{"id":35,"description":36,"titleAlert":19,"isTypeAlertWarning":8},"744","Хранение больших данных в cookie считается плохой практикой из‑за лимитов и того, что cookie «ездит» в каждом запросе.",{"id":38,"value":39,"anchor":40,"isTypeH2":8},"4517","Область видимости: Domain, Path, срок жизни","scope-domain-path-lifetime",{"id":42,"value":43,"isTypeParagraph":8},"10383","Область видимости определяет, когда браузер будет прикреплять cookie к запросу.\n\n- `Domain` задаёт, каким доменам доступна cookie, например `Domain=example.com` обычно охватывает поддомены (в рамках правил браузера)\n- `Path` ограничивает URL-пути, например `Path=/app` означает отправку на `/app/*`\n- `Expires` задаёт момент истечения (дата/время)\n- `Max-Age` задаёт время жизни в секундах, например \\(3600\\)\n- При отсутствии `Expires`/`Max-Age` cookie обычно считается «сессионной» и удаляется при завершении сессии браузера (точное поведение зависит от настроек и режима восстановления сессии)\n\nПример удаления cookie (типовой подход — истечь «в прошлом»):\n\n```\nSet-Cookie: session_id=; Path=/; Max-Age=0\n```",{"id":45,"value":46,"anchor":47,"isTypeH2":8},"4518","Атрибуты безопасности: Secure, HttpOnly, SameSite","security-attributes",{"id":49,"value":50,"isTypeParagraph":8},"10384","Атрибуты безопасности уменьшают риск утечек и атак, но не делают хранение данных в cookie «абсолютно безопасным».\n\nТаблица атрибутов:\n\n| Атрибут | Что делает | Когда применять | Типичная ошибка |\n|---|---|---|---|\n| `Secure` | Отправка только по HTTPS | Всегда для чувствительных cookie | Оставлять без `Secure` на HTTPS-сайте |\n| `HttpOnly` | Запрет доступа из JavaScript (`document.cookie`) | Для сессионных идентификаторов | Пытаться читать такую cookie на клиенте |\n| `SameSite=Lax/Strict/None` | Ограничение отправки в кросс-сайт контекстах | Защита от CSRF и трекинга | Ставить `SameSite=None` без `Secure` (обычно блокируется) |\n\nПояснение по `SameSite`:\n\n- `Lax` часто является разумным значением по умолчанию: cookie обычно отправляется при «безопасной» навигации верхнего уровня на сайт, но ограничивается в большинстве фоновых кросс-сайт запросов\n- `Strict` жёстче: cookie почти не отправляется при переходах с других сайтов\n- `None` разрешает кросс-сайт отправку, но в современных браузерах обычно требует `Secure`",{"id":52,"description":53,"titleAlert":19,"isTypeAlertInfo":8},"684","В современных браузерах распространена политика, при которой cookie без явного `SameSite` трактуется как `Lax` (поведение зависит от браузера и версии).",{"id":55,"value":56,"anchor":57,"isTypeH2":8},"4519","Современные дополнения: Partitioned (CHIPS), префиксы, Priority","modern-additions",{"id":59,"value":60,"isTypeParagraph":8},"10385","В условиях ужесточения приватности появились механизмы, ограничивающие «третьесторонние» cookie и трекинг, а также добавляющие более точные правила хранения.\n\n- `Partitioned` (CHIPS) позволяет хранить cookie в «разделённом» виде по верхнему сайту (top-level site), что полезно для встраиваемых виджетов и авторизации в iframe при минимизации трекинга\n- Префикс `__Secure-` требует наличия `Secure` и установки по HTTPS\n- Префикс `__Host-` обычно требует `Secure`, установки по HTTPS, отсутствия `Domain` и `Path=/`, что уменьшает риск подмены области видимости\n- `Priority` (например `Priority=High`) может влиять на то, какие cookie будут удержаны при переполнении лимитов\n\nПример с префиксом `__Host-`:\n\n```\nSet-Cookie: __Host-session=abc123; Path=/; Secure; HttpOnly; SameSite=Lax\n```",{"id":62,"description":63,"titleAlert":19,"isTypeAlertWarning":8},"745","Поддержка и детали `Partitioned` и политики вокруг третьесторонних cookie зависят от браузера; архитектуру аутентификации для встроенных контекстов следует проектировать с учётом этих различий.",{"id":65,"value":66,"anchor":67,"isTypeH2":8},"4520","Cookie и клиентские хранилища: что выбирать","cookies-vs-web-storage",{"id":69,"value":70,"isTypeParagraph":8},"10386","Cookie — не единственный способ хранить состояние, и часто не самый удобный для данных, которые нужны именно JavaScript-коду.\n\nСравнение:\n\n| Механизм | Авто-отправка на сервер | Доступ из JS | Типичный объём | Основные кейсы |\n|---|---|---|---|---|\n| Cookie | Да | Да, кроме `HttpOnly` | Небольшой | Сессии, флаги, совместимость с HTTP |\n| `localStorage` | Нет | Да | Больше, чем cookie | Настройки UI, кэш состояния |\n| `sessionStorage` | Нет | Да | Больше, чем cookie | Данные в рамках вкладки |\n| IndexedDB | Нет | Да | Значительно больше | Офлайн-данные, сложные структуры |\n\nОбычно идентификатор сессии хранится в cookie (часто `HttpOnly`), а сами пользовательские данные и состояние — на сервере или в других хранилищах, чтобы не увеличивать трафик и не повышать риск утечек.",{"id":72,"value":73,"anchor":74,"isTypeH2":8},"4521","Типовые сценарии использования","common-use-cases",{"id":76,"value":77,"isTypeParagraph":8},"10387","- Сессии: cookie хранит идентификатор `session_id`, сервер хранит состояние сессии и связывает его с пользователем\n- Персонализация: язык, тема, экспериментальные флаги, если нет чувствительных данных и размер мал\n- Безопасность: CSRF-токены иногда хранятся в cookie (в зависимости от паттерна), но важно понимать модель угроз и наличие XSS-защиты\n- Аналитика: исторически широко применялись третьесторонние cookie, но эта область активно ограничивается политиками приватности браузеров",{"id":79,"value":80,"anchor":81,"isTypeH2":8},"4522","Риски: XSS, CSRF, фиксация сессии","security-risks",{"id":83,"value":84,"isTypeParagraph":8},"10388","Основные угрозы и меры:\n\n- XSS: при успешной инъекции скрипта злоумышленник может прочитать не-`HttpOnly` cookie через `document.cookie`; снижение риска достигается `HttpOnly` для сессионных cookie, строгим CSP, экранированием/валидацией ввода, безопасной генерацией HTML\n- CSRF: браузер может автоматически отправить cookie на целевой сайт при кросс-сайт запросе; снижение риска достигается `SameSite=Lax/Strict`, проверкой CSRF-токенов, проверкой `Origin`/`Referer` там, где уместно\n- Фиксация сессии: навязывание жертве известного `session_id`; снижение риска достигается регенерацией идентификатора после логина и привязкой к контексту\n",{"id":86,"description":87,"titleAlert":19,"isTypeAlertWarning":8},"746","Хранение в cookie персональных данных (например, email, роли, права) без криптографической защиты считается опасным, так как cookie может быть украдена, подменена или утечь через логи/расширения.",{"id":89,"value":90,"anchor":91,"isTypeH2":8},"4523","Практика: чтение и установка на клиенте","client-side-usage",{"id":93,"value":94,"isTypeParagraph":8},"10389","Установка cookie из JavaScript возможна, но без доступа к флагу `HttpOnly` и с ограничениями на некоторые атрибуты.\n\nПример чтения и записи:\n\n```\n// Запись (часть атрибутов задаётся строкой)\ndocument.cookie = `theme=dark; Path=/; Max-Age=2592000; SameSite=Lax; Secure`;\n\n// Чтение всех доступных cookie (HttpOnly сюда не попадёт)\nconst all = document.cookie; // строка вида \"a=1; b=2\"\nconst theme = all\n  .split('; ')\n  .find(part => part.startsWith('theme='))\n  ?.split('=')[1];\n```\n\nВажно учитывать, что `document.cookie` работает со строками и требует аккуратного парсинга и кодирования значений, например через `encodeURIComponent(...)` при записи и `decodeURIComponent(...)` при чтении.",{"id":96,"value":97,"anchor":98,"isTypeH2":8},"4524","Практика: установка на сервере","server-side-usage",{"id":100,"value":101,"isTypeParagraph":8},"10390","На сервере cookie обычно устанавливается вместе с логикой сессий.\n\nПример на Node.js (HTTP):\n\n```\nimport http from 'node:http';\n\nconst server = http.createServer((req, res) => {\n  if (req.url === '/login') {\n    // Обычно тут создаётся сессия на сервере и генерируется идентификатор\n    const sid = 'abc123';\n\n    res.setHeader('Set-Cookie', [\n      `session_id=${sid}; Path=/; HttpOnly; Secure; SameSite=Lax; Max-Age=3600`,\n    ]);\n    res.statusCode = 200;\n    res.end('ok');\n    return;\n  }\n\n  const cookieHeader = req.headers.cookie ?? '';\n  res.statusCode = 200;\n  res.end(`cookies: ${cookieHeader}`);\n});\n\nserver.listen(3000);\n```\n\nНа практике идентификатор сессии должен быть непредсказуемым (криптографически стойким), а сервер должен проверять срок жизни, привязки и права доступа.",{"id":103,"value":104,"isTypeParagraph":8},"10391","Итого: cookie — это маленький фрагмент данных, устанавливаемый сервером и автоматически отправляемый браузером в HTTP-запросах по правилам области видимости и атрибутам безопасности; основное применение — сессии и небольшие настройки, а ключевые риски связаны с XSS/CSRF и неправильными атрибутами.",{"id":106,"options":107,"hint":121,"solution":122,"description":123},"1176",[108,112,115,118],{"id":109,"label":110,"isCorrect":111},"4848","Cookie — это способ хранить данные только в памяти вкладки, который не участвует в HTTP и очищается при каждом переходе на другую страницу.",false,{"id":113,"label":114,"isCorrect":8},"4849","Cookie — это небольшие данные, которые сервер задаёт браузеру через HTTP, а браузер затем автоматически отправляет их обратно в подходящих запросах, учитывая домен, путь и атрибуты.",{"id":116,"label":117,"isCorrect":111},"4850","Cookie — это механизм шифрования трафика между браузером и сервером, который заменяет HTTPS и используется для защиты паролей в формах.",{"id":119,"label":120,"isCorrect":111},"4851","Cookie — это универсальная база данных браузера для хранения больших файлов, которая синхронизируется между сайтами и всегда доступна любому домену.","Следует искать определение через пару заголовков `Set-Cookie` и `Cookie`, затем связать это с понятием «состояние поверх HTTP» и перечислить ключевые атрибуты (`Domain`, `Path`, `Max-Age/Expires`, `Secure`, `HttpOnly`, `SameSite`).","**Правильный вариант: 2** - cookie — это небольшие данные, которые сервер задаёт браузеру через HTTP, а браузер затем автоматически отправляет их обратно в подходящих запросах, учитывая домен, путь и атрибуты.","Что такое cookie?","quizQuestion",{"title":123,"description":126,"ogTitle":7,"ogDescription":126,"ogImageUrl":127,"canonical":19,"ogLocale":128,"ogSiteName":129,"ogImageType":130,"ogImageWidth":131,"ogImageHeight":132,"ogType":133,"ogUrl":19},"Cookie — небольшой фрагмент данных, который браузер хранит и отправляет сайту в HTTP. Разбор атрибутов, примеров и рисков.","/og-image.png","ru_RU","goodwebjob.ru","image_jpeg","1200","630","article",{"siteName":135,"siteUrl":136},"GOOD WEB JOB!","https://goodwebjob.ru",[138],{"label":139,"slug":140,"to":141},"Подготовка к тех.интервью","technical-interview","/technical-interview/where-to-begin",{"navigationList":143,"navigationSublist":151},[144,147],{"path":141,"isActive":111,"name":145,"icon":146,"isNavbarMobileDisabled":8},"С чего начать?","material-symbols:visibility-outline-rounded",{"path":148,"isActive":8,"name":149,"icon":150,"isNavbarMobileDisabled":111},"/technical-interview/tasks","Сборник задач","material-symbols:task-outline",[152,161,188,200,206,347,371,380,386,448,469,475],{"title":153,"list":154,"isOpened":111},"Bash",[155,158],{"name":156,"path":157,"isActive":111},"Дан фрагмент bash-скрипта: cd ~; mkdir foo... Что в нем происходит?","/technical-interview/tasks/here-is-a-fragment-of-a-bash-script-cd-mkdir-foo-what-is-happening-in-this-script",{"name":159,"path":160,"isActive":111},"Дан фрагмент bash-скрипта: target=$(ps -Af | grep $1 | head -n 1)...","/technical-interview/tasks/here-is-a-fragment-of-a-bash-script-target-ps-af-grep-1-head-n-1",{"title":162,"list":163,"isOpened":111},"CSS",[164,167,170,173,176,179,182,185],{"name":165,"path":166,"isActive":111},"Дан HTML-код. Какой будет цвет у текста «Some dummy text»?","/technical-interview/tasks/the-html-code-is-given-what-will-be-the-color-of-the-some-dummy-text",{"name":168,"path":169,"isActive":111},"Есть шаблон HTML и CSS кода. Какой будет цвет у текста «Таким образом, постоянное»?","/technical-interview/tasks/there-is-a-template-for-html-and-css-code-what-color-will-the-text-thus-constant-have",{"name":171,"path":172,"isActive":111},"Есть шаблон вложенного HTML кода. Какой будет цвет у текста «One more dummy text»?","/technical-interview/tasks/there-is-a-template-for-embedded-html-code-what-will-be-the-color-of-the-one-more-dummy-text",{"name":174,"path":175,"isActive":111},"Есть шаблон вложенного HTML кода. Будет ли display:block у body влиять на span?","/technical-interview/tasks/there-is-a-template-for-embedded-html-code-will-there-be-a-display-does-bodys-block-affect-span",{"name":177,"path":178,"isActive":111},"Есть HTML код. Будет ли font-weight на span влиять?","/technical-interview/tasks/there-is-an-html-code-will-font-weight-affect-span",{"name":180,"path":181,"isActive":111},"Flexbox и Grid, чем отличаются друг от друга?","/technical-interview/tasks/what-are-the-differences-between-flexbox-and-grid",{"name":183,"path":184,"isActive":111},"Заменяют ли Flexbox и Grid друг друга?","/technical-interview/tasks/do-flexbox-and-grid-replace-each-other",{"name":186,"path":187,"isActive":111},"Есть CSS и JS анимация. Какая между ними разница, что быстрее, что более удобно?","/technical-interview/tasks/there-are-css-and-js-animations-what-is-the-difference-between-them-and-which-is-faster-and-more-convenient",{"title":189,"list":190,"isOpened":111},"Git",[191,194,197],{"name":192,"path":193,"isActive":111},"Разрабатывал, взял закоммитил, запушил. Оказалось, что запушил не в ту ветку, точнее, коммит не в ту ветку. Какие действия?","/technical-interview/tasks/developed-it-committed-it-and-launched-it-it-turned-out-that-i-had-pushed-it-to-the-wrong-branch-or-rather-the-commit-was-in-the-wrong-branch-what-actions",{"name":195,"path":196,"isActive":111},"В git есть несколько вариантов слияния веток, какие? Чем отличаются?","/technical-interview/tasks/git-has-several-options-for-merging-branches-which-ones-how-are-they-different",{"name":198,"path":199,"isActive":111},"Какие существуют стратегии ветвления для работы команды? Что это такое?","/technical-interview/tasks/what-are-the-branching-strategies-for-the-team-what-is-it",{"title":201,"list":202,"isOpened":111},"HTML",[203],{"name":204,"path":205,"isActive":111},"Что такое HTML?","/technical-interview/tasks/what-is-html",{"title":207,"list":208,"isOpened":111},"JavaScript",[209,212,215,218,221,224,227,230,233,236,239,242,245,248,251,254,257,260,263,266,269,272,275,278,281,284,287,290,293,296,299,302,305,308,311,314,317,320,323,326,329,332,335,338,341,344],{"name":210,"path":211,"isActive":111},"Какие логические значения в console.log будут получены?","/technical-interview/tasks/prototype-what-logical-values-will-be-received-in-console-log",{"name":213,"path":214,"isActive":111},"Почему опасно писать прямо в прототипы базовых типов?","/technical-interview/tasks/why-is-it-dangerous-to-write-directly-to-the-prototypes-of-basic-types",{"name":216,"path":217,"isActive":111},"Что вернёт следующий код? Object.create(null).hasOwnProperty('toString')","/technical-interview/tasks/what-will-the-following-code-return-object-create-null-has-own-property-to-string",{"name":219,"path":220,"isActive":111},"Какое значение выведет консоль с object.property?","/technical-interview/tasks/what-value-will-the-console-output-with-object-property",{"name":222,"path":223,"isActive":111},"Что выведется в console.log([arr[0](), arr[0]()])?","/technical-interview/tasks/what-will-be-displayed-in-console-log-arr-0-arr-0",{"name":225,"path":226,"isActive":111},"Что выведет console.log в результате выполнения цикла while?","/technical-interview/tasks/what-will-console-log-output-as-a-result-of-executing-the-while-loop",{"name":228,"path":229,"isActive":111},"Есть функция и объект. Напишите все известные вам способы, чтобы вывести в консоли значение x из объекта, используя функцию","/technical-interview/tasks/there-is-a-function-and-an-object-write-all-the-ways-you-know-to-output-the-value-of-x-from-an-object-in-the-console-using-the-function",{"name":231,"path":232,"isActive":111},"Что вернёт метод book.getUpperName()?","/technical-interview/tasks/what-will-the-book-get-upper-name-method-return",{"name":234,"path":235,"isActive":111},"Переменные объявлены следующим образом: a=3; b=«hello»;. Укажите правильное утверждение","/technical-interview/tasks/variables-are-declared-as-follows-specify-the-correct-statement",{"name":237,"path":238,"isActive":111},"Что выведет консоль в случае присвоения свойства массиву по строковому положительному индексу?","/technical-interview/tasks/what-will-the-console-display-if-a-property-is-assigned-to-an-array-using-a-positive-string-index",{"name":240,"path":241,"isActive":111},"Что выведет консоль в случае присвоения свойства массиву по строковому отрицательному индексу?","/technical-interview/tasks/what-will-the-console-display-if-a-property-is-assigned-to-an-array-using-a-negative-string-index",{"name":243,"path":244,"isActive":111},"Что выведет консоль в случае удаления элемента массива с помощью оператора delete?","/technical-interview/tasks/what-will-the-console-output-if-an-array-element-is-deleted-using-the-delete-operator",{"name":246,"path":247,"isActive":111},"Что вернёт этот код: typeof (function(){})()","/technical-interview/tasks/what-this-code-will-return-typeof-function",{"name":249,"path":250,"isActive":111},"Что получится в результате передачи объекта как аргумента в функцию и выполнения кода?","/technical-interview/tasks/what-will-happen-when-an-object-is-passed-as-an-argument-to-a-function-and-the-code-is-executed",{"name":252,"path":253,"isActive":111},"Какие способы объявления функции есть в JavaScript?","/technical-interview/tasks/what-are-the-ways-to-declare-a-function-in-javascript",{"name":255,"path":256,"isActive":111},"Что такое this в JavaScript?","/technical-interview/tasks/what-is-this-in-javascript",{"name":258,"path":259,"isActive":111},"Что такое Event Loop, как работает?","/technical-interview/tasks/what-is-an-event-loop-and-how-does-it-work",{"name":261,"path":262,"isActive":111},"Что будет, если вызвать typeof на необъявленной переменной?","/technical-interview/tasks/what-happens-if-you-call-typeof-on-an-undeclared-variable",{"name":264,"path":265,"isActive":111},"Что показывает оператор typeof в JavaScript?","/technical-interview/tasks/what-does-the-typeof-operator-show-in-javascript",{"name":267,"path":268,"isActive":111},"Какие типы данных существует в JavaScript?","/technical-interview/tasks/what-types-of-data-exist-in-javascript",{"name":270,"path":271,"isActive":111},"Какую структуру использовать для хранения упорядоченного списка строк в JavaScript?","/technical-interview/tasks/what-is-the-best-structure-to-use-for-storing-an-ordered-list-of-strings-in-javascript",{"name":273,"path":274,"isActive":111},"Что вернет typeof для массива?","/technical-interview/tasks/what-will-typeof-return-for-an-array",{"name":276,"path":277,"isActive":111},"Почему оператор typeof, применённый к массиву, возвращает объект?","/technical-interview/tasks/why-does-the-typeof-operator-applied-to-an-array-return-an-object",{"name":279,"path":280,"isActive":111},"Если нужно хранить список уникальных строк, какую структуру данных выбрать?","/technical-interview/tasks/if-you-need-to-store-a-list-of-unique-strings-which-data-structure-should-i-choose",{"name":282,"path":283,"isActive":111},"Что возвращает typeof для new Set в JavaScript?","/technical-interview/tasks/what-does-typeof-return-for-new-set-in-javascript",{"name":285,"path":286,"isActive":111},"Почему в JavaScript два объекта с одинаковым содержимым при сравнении возвращают false?","/technical-interview/tasks/why-do-two-objects-with-the-same-content-return-false-when-compared-in-javascript",{"name":288,"path":289,"isActive":111},"В чем разница между микро- и макро-тасками в JavaScript?","/technical-interview/tasks/what-is-the-difference-between-micro-and-macro-tasks-in-javascript",{"name":291,"path":292,"isActive":111},"arr.push(0) повлияет на массив так же, как если бы мы выполнили...","/technical-interview/tasks/arr-push-0-will-affect-the-array-in-the-same-way-as-if-we-performed",{"name":294,"path":295,"isActive":111},"Вернуть массив от 1 до n, где числа, кратные 3, заменены на 'fizz', кратные 5 - на 'buzz', а кратные и 3, и 5 одновременно - на 'fizzbuzz'","/technical-interview/tasks/returns-an-array-from-1-to-n-replacing-numbers-that-are-multiples-of-3-with-fizz-numbers-that-are-multiples-of-5-with-buzz-and-numbers-that-are-multiples-of-both-3-and-5-with-fizzbuzz",{"name":297,"path":298,"isActive":111},"Дана строка: 'one.two.three.four.five'. Необходимо из строки сделать вложенный объект","/technical-interview/tasks/the-string-one-two-three-four-five-is-given-it-is-necessary-to-make-a-nested-object-out-of-the-string",{"name":300,"path":301,"isActive":111},"Дано дерево (вложенный объект), надо найти сумму всех вершин","/technical-interview/tasks/given-a-tree-nested-object-it-is-necessary-to-find-the-sum-of-all-vertices",{"name":303,"path":304,"isActive":111},"Для каждого вложенного объекта нужно добавить свойство level, которое равняется числу - номер вложенности","/technical-interview/tasks/for-each-nested-object-you-need-to-add-the-level-property-which-is-equal-to-a-number-the-nesting-number",{"name":306,"path":307,"isActive":111},"Для каждой ветви дерева записать номер вложенности данной ветви","/technical-interview/tasks/for-each-branch-of-the-tree-write-down-the-nesting-number-of-this-branch",{"name":309,"path":310,"isActive":111},"Есть массив, в котором лежат объекты с датами, необходимо отсортировать даты по возрастанию","/technical-interview/tasks/there-is-an-array-containing-objects-with-dates-that-need-to-be-sorted-by-date",{"name":312,"path":313,"isActive":111},"Есть слова в массиве, необходимо определить, состоят ли они из одних и тех же букв","/technical-interview/tasks/there-are-words-in-the-array-it-is-necessary-to-determine-whether-they-consist-of-the-same-letters",{"name":315,"path":316,"isActive":111},"Есть строка, состоящая из разных скобок, необходимо проверить, закрыты ли все","/technical-interview/tasks/there-is-a-string-consisting-of-different-brackets-it-is-necessary-to-check-whether-all-are-closed",{"name":318,"path":319,"isActive":111}," Найти в массиве неповторяющиеся числа","/technical-interview/tasks/find-non-repeating-numbers-in-an-array",{"name":321,"path":322,"isActive":111},"Напишите функцию, который сделает из массива объект","/technical-interview/tasks/write-a-function-that-will-make-an-object-out-of-an-array",{"name":324,"path":325,"isActive":111},"Необходимо проверить, являются ли две строки анаграммами друг друга","/technical-interview/tasks/checks-whether-two-strings-are-anagrams-of-each-other",{"name":327,"path":328,"isActive":111},"Нечётные числа должны отсортироваться по возрастанию, а чётные должны остаться на своих местах","/technical-interview/tasks/odd-numbers-should-be-sorted-in-ascending-order-and-even-numbers-should-remain-in-their-original-positions",{"name":330,"path":331,"isActive":111},"Определить, является ли слово палиндромом","/technical-interview/tasks/determines-whether-a-word-is-a-palindrome",{"name":333,"path":334,"isActive":111},"«Расплющивание» массива","/technical-interview/tasks/flattening-the-array",{"name":336,"path":337,"isActive":111},"Реализовать функцию, принимающую аргументы \"*\", \"1\", \"b\", \"1c\" и возвращающую строку \"1*b*1c\"","/technical-interview/tasks/implement-a-function-that-accepts-arguments-1-b-1c-and-the-return-string-1-b-1c",{"name":339,"path":340,"isActive":111},"Сжатие строк","/technical-interview/tasks/string-compression",{"name":342,"path":343,"isActive":111},"Уникализация значений в массиве","/technical-interview/tasks/unifying-values-in-an-array",{"name":345,"path":346,"isActive":111},"Числа от 1 до 100 находятся в массиве, они хаотично перемешанные, но в нём не хватает одного числа из этой последовательности. Необходимо найти его","/technical-interview/tasks/the-numbers-from-1-to-100-are-in-the-array-they-are-randomly-mixed-but-it-lacks-one-number-from-this-sequence-it-is-necessary-to-find-him",{"title":348,"list":349,"isOpened":111},"React",[350,353,356,359,362,365,368],{"name":351,"path":352,"isActive":111},"Для чего нужен React, какие он решает проблемы?","/technical-interview/tasks/what-is-react-used-for-and-what-problems-does-it-solve",{"name":354,"path":355,"isActive":111},"Какой механизм лежит в основе оптимизации обновлений DOM в React?","/technical-interview/tasks/what-is-the-underlying-mechanism-for-optimizing-dom-updates-in-react",{"name":357,"path":358,"isActive":111},"Если убрать в React VDOM/Fiber, и вручную изменять DOM, разве это не оптимально?","/technical-interview/tasks/if-you-remove-the-vdom-fiber-in-react-and-manually-change-the-dom-isn-t-that-optimal",{"name":360,"path":361,"isActive":111},"Есть блок кода. Что в реальном DOM изменится после нажатия на кнопку?","/technical-interview/tasks/there-is-a-block-of-code-what-changes-in-the-real-dom-after-clicking-the-button",{"name":363,"path":364,"isActive":111},"Есть код, в котором список и кнопка. Что в реальном DOM изменится после нажатия на кнопку?","/technical-interview/tasks/there-is-a-code-in-which-there-is-a-list-and-a-button-what-will-change-in-the-real-dom-after-clicking-on-the-button",{"name":366,"path":367,"isActive":111},"Зачем нужен Redux (Mobx/Effector)? Зачем нужен менеджер состояния? Какие проблемы решает?","/technical-interview/tasks/why-do-we-need-redux-mobx-effector-why-do-we-need-a-state-manager-what-problems-does-it-solve",{"name":369,"path":370,"isActive":111},"Что мешает организовать централизованное состояние без менеджера состояния? Если организовать состояние механизмами реакта: контекстом, стейтом, в чем проблема? Что менеджеры состояния привносят?","/technical-interview/tasks/what-prevents-you-from-organizing-a-centralized-state-without-a-state-manager-if-you-organize-the-state-using-react-context-and-state-mechanisms-what-is-the-problem-what-do-state-managers-add",{"title":372,"list":373,"isOpened":111},"Алгоритмы",[374,377],{"name":375,"path":376,"isActive":111},"Что такое алгоритмическая сложность?","/technical-interview/tasks/what-is-algorithmic-complexity",{"name":378,"path":379,"isActive":111},"Какая алгоритмическая сложность у \"быстрой сортировки\"?","/technical-interview/tasks/what-is-the-algorithmic-complexity-of-quick-sort",{"title":381,"list":382,"isOpened":111},"Дебаггинг",[383],{"name":384,"path":385,"isActive":111},"Как диагностировать и исправить нежелательное изменение цвета фона по клику на кнопку, если исходный код сайта запутан и недоступен для прямого чтения?","/technical-interview/tasks/how-can-diagnose-and-fix-unwanted-background-color-changes-when-clicking-on-a-button-if-the-source-code-of-the-site-is-confusing-and-inaccessible-to-direct-reading",{"title":387,"list":388,"isOpened":111},"Компьютерные сети",[389,392,395,398,401,404,407,410,413,416,419,422,425,427,430,433,436,439,442,445],{"name":390,"path":391,"isActive":111},"Как браузер после ввода домена понимает, откуда брать сайт?","/technical-interview/tasks/how-does-the-browser-know-where-to-get-the-website-after-entering-the-domain",{"name":393,"path":394,"isActive":111},"Что такое DNS, как DNS находит нужный IP-адрес?","/technical-interview/tasks/what-is-dns-and-how-does-dns-find-the-correct-ip-address",{"name":396,"path":397,"isActive":111},"Как домен попадает в DNS в таблицу соответствия: домен – ip","/technical-interview/tasks/how-does-a-domain-get-into-the-dns-mapping-table-domain-ip",{"name":399,"path":400,"isActive":111},"Как браузер решает, какое соединение ему открывать, TCP или UDP?","/technical-interview/tasks/how-does-a-browser-decide-whether-to-open-a-tcp-or-udp-connection",{"name":402,"path":403,"isActive":111},"Ключевые отличия TCP и UDP","/technical-interview/tasks/key-differences-between-tcp-and-udp",{"name":405,"path":406,"isActive":111},"\"TCP/IP\" - кем является TCP, а кем IP в данном случае?","/technical-interview/tasks/tcp-ip-who-is-tcp-and-who-is-ip-in-this-case",{"name":408,"path":409,"isActive":111},"Что такое HTTP и из чего состоит?","/technical-interview/tasks/what-is-http-and-what-does-it-consist-of",{"name":411,"path":412,"isActive":111},"Что такое заголовки в HTTP и зачем они нужны?","/technical-interview/tasks/what-are-http-headers-and-why-do-we-need-them",{"name":414,"path":415,"isActive":111},"Что такое параметры в HTTP?","/technical-interview/tasks/what-are-http-parameters",{"name":417,"path":418,"isActive":111},"Где находится HTML-код в структуре HTTP-ответа?","/technical-interview/tasks/where-is-the-html-code-located-in-the-http-response-structure",{"name":420,"path":421,"isActive":111},"Чем отличаются 1.0, 1.1, 2.0, 3.0 версии HTTP?","/technical-interview/tasks/what-are-the-differences-between-http-versions-1-0-1-1-2-0-and-3-0",{"name":423,"path":424,"isActive":111},"Пользователь авторизован на сайте. Как сервер узнает об этом с последующими другими заходами, что «я – авторизованный пользователь»?","/technical-interview/tasks/the-user-is-logged-in-on-the-website-how-does-the-server-know-that-i-am-an-authorized-user-when-the-user-logs-in-again",{"name":123,"path":426,"isActive":111},"/technical-interview/tasks/what-is-a-cookie",{"name":428,"path":429,"isActive":111},"Кто является инициатором записи cookie в браузере?","/technical-interview/tasks/who-initiates-the-cookie-recording-in-the-browser",{"name":431,"path":432,"isActive":111},"Есть ли возможность с клиента (с браузера) управлять cookie?","/technical-interview/tasks/is-it-possible-to-manage-cookies-from-the-client-browser",{"name":434,"path":435,"isActive":111},"Верно ли утверждение, что злоумышленник, контролирующий роутер и прослушивающий трафик, может получить логины и пароли от сайтов, на которые заходит клиент?","/technical-interview/tasks/is-it-true-that-an-attacker-who-controls-a-router-and-listens-to-traffic-can-obtain-logins-and-passwords-from-websites-that-a-client-visits",{"name":437,"path":438,"isActive":111},"Всё, что идет по HTTPS – оно защищено?","/technical-interview/tasks/is-everything-that-goes-through-https-secure",{"name":440,"path":441,"isActive":111},"Все данные зашифрованы, используется https. Хакер взламывает dns и делает подмену одного ip на другой, на фишинговый сайт. В этом случае, злоумышленник может получить данные (логин \\ пароль)?","/technical-interview/tasks/all-data-is-encrypted-https-is-used-let-s-assume-a-hacker-hacks-the-dns-and-makes-a-substitution-of-one-ip-for-another-a-phishing-site",{"name":443,"path":444,"isActive":111},"Есть веб-приложение. Помимо HTTP, какие протоколы того же уровня (Application Layer) можно дополнительно использовать в веб-приложении в браузере?","/technical-interview/tasks/there-is-a-web-application-in-addition-to-http-what-other-protocols-of-the-same-level-application-layer-can-be-used-in-the-web-application-in-browser",{"name":446,"path":447,"isActive":111},"Каким способом может выполняться авторизация пользователя на сайте?","/technical-interview/tasks/how-can-a-user-be-authorized-on-a-website",{"title":449,"list":450,"isOpened":111},"Отрисовка в браузере",[451,454,457,460,463,466],{"name":452,"path":453,"isActive":111},"Что происходит, когда HTTP прислал HTML? Что браузер дальше делает c HTML с учетом того, что она валидная?","/technical-interview/tasks/what-happens-when-http-sends-html-what-does-the-browser-do-with-this-html-given-that-it-is-valid",{"name":455,"path":456,"isActive":111},"Как браузер парсит JavaScript и изображения при рендеринге?","/technical-interview/tasks/how-the-browser-parses-javascript-and-images-when-rendering",{"name":458,"path":459,"isActive":111},"Что в браузере блокирует рендеринг страницы?","/technical-interview/tasks/what-is-blocking-the-page-rendering-in-the-browser",{"name":461,"path":462,"isActive":111},"Что такое DOM в браузере? Что такое CSSOM?","/technical-interview/tasks/what-is-dom-in-a-browser-what-is-cssom",{"name":464,"path":465,"isActive":111},"Что является узлами в DOM?","/technical-interview/tasks/what-are-nodes-in-the-dom",{"name":467,"path":468,"isActive":111},"Из чего состоит CSSOM?","/technical-interview/tasks/what-does-cssom-consist-of",{"title":470,"list":471,"isOpened":111},"Ревью кода",[472],{"name":473,"path":474,"isActive":111},"По каким характеристикам, ревьюер понимает, что данный код - хороший, а этот код - плохой?","/technical-interview/tasks/how-does-a-reviewer-know-which-code-is-good-and-which-code-is-bad",{"title":476,"list":477,"isOpened":111},"Теория вероятности",[478,481,484],{"name":479,"path":480,"isActive":111},"В комнате три человека. Какова вероятность того, что хотя бы двое из них одного пола? То есть два и более.","/technical-interview/tasks/there-are-three-people-in-the-room-what-is-the-probability-that-at-least-two-of-them-are-of-the-same-sex-that-is-two-or-more",{"name":482,"path":483,"isActive":111},"Есть монета. Ее подбрасывают пять раз подряд. Каждый раз записывается, что выпало - орел или решка. Сколько разных последовательностей орлов и решек может при этом получиться?","/technical-interview/tasks/there-is-a-coin-it-is-tossed-five-times-in-a-row-each-time-it-is-recorded-whether-it-lands-on-heads-or-tails-how-many-different-sequences-of-heads-and-tails-can-be-obtained",{"name":485,"path":486,"isActive":111},"Как гарантированно найти лёгкую фальшивую монету среди 8 за минимальное число взвешиваний на чашечных весах?","/technical-interview/tasks/how-can-you-guarantee-to-find-an-easy-fake-coin-among-8-in-the-minimum-number-of-weighings-on-a-balance-scale",{"slugs":488},[489,492,494,496,498,501,504,506,508,510,512,514,517,519,521,523,525,527,529,531,533,535,537,539,541,543,545,547,549,551,553,555,557,559,561,563,565,567,569,571,573,575,577,579,581,583,585,587,589,590,592,594,597,599,601,603,605,607,609,611,613,615,617,619,621,623,625,627,629,631,633,635,637,639,641,643,645,647,649,651,653,655,657,659,661,663,665,667,669,671,673,675,677,679,681,683,685,687,689,691,693,695,697,698,700,702,704,706],{"name":490,"value":491},"Теоретические задания","theoretical-tasks",{"name":246,"value":493},"what-this-code-will-return-typeof-function",{"name":145,"value":495},"where-to-begin",{"name":213,"value":497},"why-is-it-dangerous-to-write-directly-to-the-prototypes-of-basic-types",{"name":499,"value":500},"Backend","backend",{"name":502,"value":503},"Frontend","frontend",{"name":210,"value":505},"prototype-what-logical-values-will-be-received-in-console-log",{"name":327,"value":507},"odd-numbers-should-be-sorted-in-ascending-order-and-even-numbers-should-remain-in-their-original-positions",{"name":318,"value":509},"find-non-repeating-numbers-in-an-array",{"name":291,"value":511},"arr-push-0-will-affect-the-array-in-the-same-way-as-if-we-performed",{"name":297,"value":513},"the-string-one-two-three-four-five-is-given-it-is-necessary-to-make-a-nested-object-out-of-the-string",{"name":515,"value":516},"Реализовать функцию, похоже как в Jquery","implement-a-function-similar-to-jquery",{"name":303,"value":518},"for-each-nested-object-you-need-to-add-the-level-property-which-is-equal-to-a-number-the-nesting-number",{"name":219,"value":520},"what-value-will-the-console-output-with-object-property",{"name":222,"value":522},"what-will-be-displayed-in-console-log-arr-0-arr-0",{"name":294,"value":524},"returns-an-array-from-1-to-n-replacing-numbers-that-are-multiples-of-3-with-fizz-numbers-that-are-multiples-of-5-with-buzz-and-numbers-that-are-multiples-of-both-3-and-5-with-fizzbuzz",{"name":324,"value":526},"checks-whether-two-strings-are-anagrams-of-each-other",{"name":330,"value":528},"determines-whether-a-word-is-a-palindrome",{"name":309,"value":530},"there-is-an-array-containing-objects-with-dates-that-need-to-be-sorted-by-date",{"name":336,"value":532},"implement-a-function-that-accepts-arguments-1-b-1c-and-the-return-string-1-b-1c",{"name":300,"value":534},"given-a-tree-nested-object-it-is-necessary-to-find-the-sum-of-all-vertices",{"name":306,"value":536},"for-each-branch-of-the-tree-write-down-the-nesting-number-of-this-branch",{"name":312,"value":538},"there-are-words-in-the-array-it-is-necessary-to-determine-whether-they-consist-of-the-same-letters",{"name":345,"value":540},"the-numbers-from-1-to-100-are-in-the-array-they-are-randomly-mixed-but-it-lacks-one-number-from-this-sequence-it-is-necessary-to-find-him",{"name":315,"value":542},"there-is-a-string-consisting-of-different-brackets-it-is-necessary-to-check-whether-all-are-closed",{"name":321,"value":544},"write-a-function-that-will-make-an-object-out-of-an-array",{"name":225,"value":546},"what-will-console-log-output-as-a-result-of-executing-the-while-loop",{"name":228,"value":548},"there-is-a-function-and-an-object-write-all-the-ways-you-know-to-output-the-value-of-x-from-an-object-in-the-console-using-the-function",{"name":240,"value":550},"what-will-the-console-display-if-a-property-is-assigned-to-an-array-using-a-negative-string-index",{"name":243,"value":552},"what-will-the-console-output-if-an-array-element-is-deleted-using-the-delete-operator",{"name":342,"value":554},"unifying-values-in-an-array",{"name":333,"value":556},"flattening-the-array",{"name":231,"value":558},"what-will-the-book-get-upper-name-method-return",{"name":339,"value":560},"string-compression",{"name":237,"value":562},"what-will-the-console-display-if-a-property-is-assigned-to-an-array-using-a-positive-string-index",{"name":249,"value":564},"what-will-happen-when-an-object-is-passed-as-an-argument-to-a-function-and-the-code-is-executed",{"name":390,"value":566},"how-does-the-browser-know-where-to-get-the-website-after-entering-the-domain",{"name":396,"value":568},"how-does-a-domain-get-into-the-dns-mapping-table-domain-ip",{"name":399,"value":570},"how-does-a-browser-decide-whether-to-open-a-tcp-or-udp-connection",{"name":402,"value":572},"key-differences-between-tcp-and-udp",{"name":405,"value":574},"tcp-ip-who-is-tcp-and-who-is-ip-in-this-case",{"name":408,"value":576},"what-is-http-and-what-does-it-consist-of",{"name":411,"value":578},"what-are-http-headers-and-why-do-we-need-them",{"name":414,"value":580},"what-are-http-parameters",{"name":417,"value":582},"where-is-the-html-code-located-in-the-http-response-structure",{"name":204,"value":584},"what-is-html",{"name":420,"value":586},"what-are-the-differences-between-http-versions-1-0-1-1-2-0-and-3-0",{"name":423,"value":588},"the-user-is-logged-in-on-the-website-how-does-the-server-know-that-i-am-an-authorized-user-when-the-user-logs-in-again",{"name":123,"value":12},{"name":428,"value":591},"who-initiates-the-cookie-recording-in-the-browser",{"name":431,"value":593},"is-it-possible-to-manage-cookies-from-the-client-browser",{"name":595,"value":596},"Лайвкодинг","livecoding",{"name":216,"value":598},"what-will-the-following-code-return-object-create-null-has-own-property-to-string",{"name":437,"value":600},"is-everything-that-goes-through-https-secure",{"name":440,"value":602},"all-data-is-encrypted-https-is-used-let-s-assume-a-hacker-hacks-the-dns-and-makes-a-substitution-of-one-ip-for-another-a-phishing-site",{"name":443,"value":604},"there-is-a-web-application-in-addition-to-http-what-other-protocols-of-the-same-level-application-layer-can-be-used-in-the-web-application-in-browser",{"name":455,"value":606},"how-the-browser-parses-javascript-and-images-when-rendering",{"name":452,"value":608},"what-happens-when-http-sends-html-what-does-the-browser-do-with-this-html-given-that-it-is-valid",{"name":458,"value":610},"what-is-blocking-the-page-rendering-in-the-browser",{"name":461,"value":612},"what-is-dom-in-a-browser-what-is-cssom",{"name":464,"value":614},"what-are-nodes-in-the-dom",{"name":467,"value":616},"what-does-cssom-consist-of",{"name":165,"value":618},"the-html-code-is-given-what-will-be-the-color-of-the-some-dummy-text",{"name":168,"value":620},"there-is-a-template-for-html-and-css-code-what-color-will-the-text-thus-constant-have",{"name":171,"value":622},"there-is-a-template-for-embedded-html-code-what-will-be-the-color-of-the-one-more-dummy-text",{"name":174,"value":624},"there-is-a-template-for-embedded-html-code-will-there-be-a-display-does-bodys-block-affect-span",{"name":177,"value":626},"there-is-an-html-code-will-font-weight-affect-span",{"name":180,"value":628},"what-are-the-differences-between-flexbox-and-grid",{"name":183,"value":630},"do-flexbox-and-grid-replace-each-other",{"name":186,"value":632},"there-are-css-and-js-animations-what-is-the-difference-between-them-and-which-is-faster-and-more-convenient",{"name":149,"value":634},"tasks",{"name":252,"value":636},"what-are-the-ways-to-declare-a-function-in-javascript",{"name":255,"value":638},"what-is-this-in-javascript",{"name":258,"value":640},"what-is-an-event-loop-and-how-does-it-work",{"name":261,"value":642},"what-happens-if-you-call-typeof-on-an-undeclared-variable",{"name":264,"value":644},"what-does-the-typeof-operator-show-in-javascript",{"name":267,"value":646},"what-types-of-data-exist-in-javascript",{"name":270,"value":648},"what-is-the-best-structure-to-use-for-storing-an-ordered-list-of-strings-in-javascript",{"name":273,"value":650},"what-will-typeof-return-for-an-array",{"name":276,"value":652},"why-does-the-typeof-operator-applied-to-an-array-return-an-object",{"name":279,"value":654},"if-you-need-to-store-a-list-of-unique-strings-which-data-structure-should-i-choose",{"name":282,"value":656},"what-does-typeof-return-for-new-set-in-javascript",{"name":351,"value":658},"what-is-react-used-for-and-what-problems-does-it-solve",{"name":357,"value":660},"if-you-remove-the-vdom-fiber-in-react-and-manually-change-the-dom-isn-t-that-optimal",{"name":360,"value":662},"there-is-a-block-of-code-what-changes-in-the-real-dom-after-clicking-the-button",{"name":363,"value":664},"there-is-a-code-in-which-there-is-a-list-and-a-button-what-will-change-in-the-real-dom-after-clicking-on-the-button",{"name":366,"value":666},"why-do-we-need-redux-mobx-effector-why-do-we-need-a-state-manager-what-problems-does-it-solve",{"name":384,"value":668},"how-can-diagnose-and-fix-unwanted-background-color-changes-when-clicking-on-a-button-if-the-source-code-of-the-site-is-confusing-and-inaccessible-to-direct-reading",{"name":192,"value":670},"developed-it-committed-it-and-launched-it-it-turned-out-that-i-had-pushed-it-to-the-wrong-branch-or-rather-the-commit-was-in-the-wrong-branch-what-actions",{"name":195,"value":672},"git-has-several-options-for-merging-branches-which-ones-how-are-they-different",{"name":198,"value":674},"what-are-the-branching-strategies-for-the-team-what-is-it",{"name":473,"value":676},"how-does-a-reviewer-know-which-code-is-good-and-which-code-is-bad",{"name":156,"value":678},"here-is-a-fragment-of-a-bash-script-cd-mkdir-foo-what-is-happening-in-this-script",{"name":159,"value":680},"here-is-a-fragment-of-a-bash-script-target-ps-af-grep-1-head-n-1",{"name":375,"value":682},"what-is-algorithmic-complexity",{"name":378,"value":684},"what-is-the-algorithmic-complexity-of-quick-sort",{"name":285,"value":686},"why-do-two-objects-with-the-same-content-return-false-when-compared-in-javascript",{"name":446,"value":688},"how-can-a-user-be-authorized-on-a-website",{"name":288,"value":690},"what-is-the-difference-between-micro-and-macro-tasks-in-javascript",{"name":479,"value":692},"there-are-three-people-in-the-room-what-is-the-probability-that-at-least-two-of-them-are-of-the-same-sex-that-is-two-or-more",{"name":482,"value":694},"there-is-a-coin-it-is-tossed-five-times-in-a-row-each-time-it-is-recorded-whether-it-lands-on-heads-or-tails-how-many-different-sequences-of-heads-and-tails-can-be-obtained",{"name":485,"value":696},"how-can-you-guarantee-to-find-an-easy-fake-coin-among-8-in-the-minimum-number-of-weighings-on-a-balance-scale",{"name":139,"value":140},{"name":434,"value":699},"is-it-true-that-an-attacker-who-controls-a-router-and-listens-to-traffic-can-obtain-logins-and-passwords-from-websites-that-a-client-visits",{"name":393,"value":701},"what-is-dns-and-how-does-dns-find-the-correct-ip-address",{"name":234,"value":703},"variables-are-declared-as-follows-specify-the-correct-statement",{"name":354,"value":705},"what-is-the-underlying-mechanism-for-optimizing-dom-updates-in-react",{"name":369,"value":707},"what-prevents-you-from-organizing-a-centralized-state-without-a-state-manager-if-you-organize-the-state-using-react-context-and-state-mechanisms-what-is-the-problem-what-do-state-managers-add",{"cooperation":709,"copyright":712,"reportError":713,"socialNetwork":715},{"link":710,"title":711},"https://t.me/baurinanton","Сотрудничество","© “GOOD WEB JOB!”",{"label":714,"link":710},"Сообщить об ошибке",{"label":716,"socialNetworkList":717},"Мы в соцсетях:",[718,721,724],{"icon":19,"link":719,"title":720},"https://max.ru/u/f9LHodD0cOKMaukdnnahTeL5pwvjrPfUaZ4S8_1rsNy9I9qsmc9Ar3kP_y8","Max",{"icon":722,"link":710,"title":723},"ic:baseline-telegram","Telegram",{"icon":725,"link":726,"title":727},"ri:vk-fill","https://vk.com/baurinanton","VK",{"data":729,"body":730},{},{"type":731,"children":732},"root",[733],{"type":734,"tag":735,"props":736,"children":737},"element","p",{},[738],{"type":739,"value":123},"text",{"data":741,"body":742},{},{"type":731,"children":743},[744],{"type":734,"tag":735,"props":745,"children":746},{},[747],{"type":739,"value":110},{"data":749,"body":750},{},{"type":731,"children":751},[752],{"type":734,"tag":735,"props":753,"children":754},{},[755],{"type":739,"value":114},{"data":757,"body":758},{},{"type":731,"children":759},[760],{"type":734,"tag":735,"props":761,"children":762},{},[763],{"type":739,"value":117},{"data":765,"body":766},{},{"type":731,"children":767},[768],{"type":734,"tag":735,"props":769,"children":770},{},[771],{"type":739,"value":120},{"data":773,"body":774},{},{"type":731,"children":775},[776],{"type":734,"tag":735,"props":777,"children":778},{},[779,781,788,790,796,798,804,806,812,813,819,820,826,827,833,834,840],{"type":739,"value":780},"Следует искать определение через пару заголовков ",{"type":734,"tag":782,"props":783,"children":785},"code",{"className":784},[],[786],{"type":739,"value":787},"Set-Cookie",{"type":739,"value":789}," и ",{"type":734,"tag":782,"props":791,"children":793},{"className":792},[],[794],{"type":739,"value":795},"Cookie",{"type":739,"value":797},", затем связать это с понятием «состояние поверх HTTP» и перечислить ключевые атрибуты (",{"type":734,"tag":782,"props":799,"children":801},{"className":800},[],[802],{"type":739,"value":803},"Domain",{"type":739,"value":805},", ",{"type":734,"tag":782,"props":807,"children":809},{"className":808},[],[810],{"type":739,"value":811},"Path",{"type":739,"value":805},{"type":734,"tag":782,"props":814,"children":816},{"className":815},[],[817],{"type":739,"value":818},"Max-Age/Expires",{"type":739,"value":805},{"type":734,"tag":782,"props":821,"children":823},{"className":822},[],[824],{"type":739,"value":825},"Secure",{"type":739,"value":805},{"type":734,"tag":782,"props":828,"children":830},{"className":829},[],[831],{"type":739,"value":832},"HttpOnly",{"type":739,"value":805},{"type":734,"tag":782,"props":835,"children":837},{"className":836},[],[838],{"type":739,"value":839},"SameSite",{"type":739,"value":841},").",{"data":843,"body":844},{},{"type":731,"children":845},[846],{"type":734,"tag":735,"props":847,"children":848},{},[849,855],{"type":734,"tag":850,"props":851,"children":852},"strong",{},[853],{"type":739,"value":854},"Правильный вариант: 2",{"type":739,"value":856}," - cookie — это небольшие данные, которые сервер задаёт браузеру через HTTP, а браузер затем автоматически отправляет их обратно в подходящих запросах, учитывая домен, путь и атрибуты.",{"data":858,"body":859},{},{"type":731,"children":860},[861,866],{"type":734,"tag":735,"props":862,"children":863},{},[864],{"type":739,"value":865},"Cookie — это небольшой фрагмент данных (пара «имя=значение» с метаданными), который сервер просит браузер сохранить, а браузер затем автоматически отправляет обратно на сервер при последующих запросах в рамках заданной области видимости (домен, путь, контекст).",{"type":734,"tag":735,"props":867,"children":868},{},[869],{"type":739,"value":870},"Ключевая идея cookie — привязать несколько независимых HTTP-запросов к единому контексту, например к авторизованной сессии, предпочтениям интерфейса или состоянию корзины, если оно хранится на стороне сервера.",{"data":872,"body":873},{},{"type":731,"children":874},[875],{"type":734,"tag":735,"props":876,"children":877},{},[878],{"type":739,"value":18},{"data":880,"body":881},{},{"type":731,"children":882},[883,902,907,919,924,933,938],{"type":734,"tag":735,"props":884,"children":885},{},[886,888,893,895,900],{"type":739,"value":887},"Cookie устанавливается сервером через заголовок ",{"type":734,"tag":782,"props":889,"children":891},{"className":890},[],[892],{"type":739,"value":787},{"type":739,"value":894}," в HTTP-ответе, а затем возвращается браузером через заголовок ",{"type":734,"tag":782,"props":896,"children":898},{"className":897},[],[899],{"type":739,"value":795},{"type":739,"value":901}," в HTTP-запросе.",{"type":734,"tag":735,"props":903,"children":904},{},[905],{"type":739,"value":906},"Пример ответа сервера с установкой cookie:",{"type":734,"tag":908,"props":909,"children":913},"pre",{"className":910,"code":912,"language":739},[911],"language-text","HTTP/1.1 200 OK\nContent-Type: text/html; charset=utf-8\nSet-Cookie: session_id=abc123; Path=/; HttpOnly; Secure; SameSite=Lax; Max-Age=3600\n\n\u003Chtml>...\u003C/html>\n",[914],{"type":734,"tag":782,"props":915,"children":917},{"__ignoreMap":916},"",[918],{"type":739,"value":912},{"type":734,"tag":735,"props":920,"children":921},{},[922],{"type":739,"value":923},"Пример последующего запроса браузера к тому же сайту:",{"type":734,"tag":908,"props":925,"children":928},{"className":926,"code":927,"language":739},[911],"GET /profile HTTP/1.1\nHost: example.com\nCookie: session_id=abc123\n",[929],{"type":734,"tag":782,"props":930,"children":931},{"__ignoreMap":916},[932],{"type":739,"value":927},{"type":734,"tag":735,"props":934,"children":935},{},[936],{"type":739,"value":937},"Схема обмена:",{"type":734,"tag":908,"props":939,"children":942},{"className":940,"code":941,"language":739},[911],"    ┌──────────┐                 ┌────────────┐\n    │ Браузер  │ 1) Запрос       │   Сервер   │\n    │          ├────────────────▶│            │\n    │          │                 │ 2) Ответ   │\n    │          │  Set-Cookie     │            │\n    │          │◀────────────────┤            │\n    │          │ 3) След. запрос │            │\n    │          │  Cookie: ...    │            │\n    └──────────┘                 └────────────┘\n",[943],{"type":734,"tag":782,"props":944,"children":945},{"__ignoreMap":916},[946],{"type":739,"value":941},{"data":948,"body":949},{},{"type":731,"children":950},[951,956],{"type":734,"tag":735,"props":952,"children":953},{},[954],{"type":739,"value":955},"Cookie имеет ограниченный размер (типично около (4096) байт на одну cookie) и ограничения по количеству на домен (зависит от браузера и политики, часто десятки/сотни).",{"type":734,"tag":735,"props":957,"children":958},{},[959],{"type":739,"value":960},"Cookie отправляется в каждом подходящем HTTP-запросе автоматически, поэтому увеличение размера и количества cookie повышает сетевые накладные расходы и может замедлять загрузку страниц.",{"data":962,"body":963},{},{"type":731,"children":964},[965],{"type":734,"tag":735,"props":966,"children":967},{},[968],{"type":739,"value":36},{"data":970,"body":971},{},{"type":731,"children":972},[973,978,1066,1071],{"type":734,"tag":735,"props":974,"children":975},{},[976],{"type":739,"value":977},"Область видимости определяет, когда браузер будет прикреплять cookie к запросу.",{"type":734,"tag":979,"props":980,"children":981},"ul",{},[982,1001,1025,1036,1047],{"type":734,"tag":983,"props":984,"children":985},"li",{},[986,991,993,999],{"type":734,"tag":782,"props":987,"children":989},{"className":988},[],[990],{"type":739,"value":803},{"type":739,"value":992}," задаёт, каким доменам доступна cookie, например ",{"type":734,"tag":782,"props":994,"children":996},{"className":995},[],[997],{"type":739,"value":998},"Domain=example.com",{"type":739,"value":1000}," обычно охватывает поддомены (в рамках правил браузера)",{"type":734,"tag":983,"props":1002,"children":1003},{},[1004,1009,1011,1017,1019],{"type":734,"tag":782,"props":1005,"children":1007},{"className":1006},[],[1008],{"type":739,"value":811},{"type":739,"value":1010}," ограничивает URL-пути, например ",{"type":734,"tag":782,"props":1012,"children":1014},{"className":1013},[],[1015],{"type":739,"value":1016},"Path=/app",{"type":739,"value":1018}," означает отправку на ",{"type":734,"tag":782,"props":1020,"children":1022},{"className":1021},[],[1023],{"type":739,"value":1024},"/app/*",{"type":734,"tag":983,"props":1026,"children":1027},{},[1028,1034],{"type":734,"tag":782,"props":1029,"children":1031},{"className":1030},[],[1032],{"type":739,"value":1033},"Expires",{"type":739,"value":1035}," задаёт момент истечения (дата/время)",{"type":734,"tag":983,"props":1037,"children":1038},{},[1039,1045],{"type":734,"tag":782,"props":1040,"children":1042},{"className":1041},[],[1043],{"type":739,"value":1044},"Max-Age",{"type":739,"value":1046}," задаёт время жизни в секундах, например (3600)",{"type":734,"tag":983,"props":1048,"children":1049},{},[1050,1052,1057,1059,1064],{"type":739,"value":1051},"При отсутствии ",{"type":734,"tag":782,"props":1053,"children":1055},{"className":1054},[],[1056],{"type":739,"value":1033},{"type":739,"value":1058},"/",{"type":734,"tag":782,"props":1060,"children":1062},{"className":1061},[],[1063],{"type":739,"value":1044},{"type":739,"value":1065}," cookie обычно считается «сессионной» и удаляется при завершении сессии браузера (точное поведение зависит от настроек и режима восстановления сессии)",{"type":734,"tag":735,"props":1067,"children":1068},{},[1069],{"type":739,"value":1070},"Пример удаления cookie (типовой подход — истечь «в прошлом»):",{"type":734,"tag":908,"props":1072,"children":1075},{"className":1073,"code":1074,"language":739},[911],"Set-Cookie: session_id=; Path=/; Max-Age=0\n",[1076],{"type":734,"tag":782,"props":1077,"children":1078},{"__ignoreMap":916},[1079],{"type":739,"value":1074},{"data":1081,"body":1082},{},{"type":731,"children":1083},[1084,1089,1094,1241,1253],{"type":734,"tag":735,"props":1085,"children":1086},{},[1087],{"type":739,"value":1088},"Атрибуты безопасности уменьшают риск утечек и атак, но не делают хранение данных в cookie «абсолютно безопасным».",{"type":734,"tag":735,"props":1090,"children":1091},{},[1092],{"type":739,"value":1093},"Таблица атрибутов:",{"type":734,"tag":1095,"props":1096,"children":1097},"table",{},[1098,1127],{"type":734,"tag":1099,"props":1100,"children":1101},"thead",{},[1102],{"type":734,"tag":1103,"props":1104,"children":1105},"tr",{},[1106,1112,1117,1122],{"type":734,"tag":1107,"props":1108,"children":1109},"th",{},[1110],{"type":739,"value":1111},"Атрибут",{"type":734,"tag":1107,"props":1113,"children":1114},{},[1115],{"type":739,"value":1116},"Что делает",{"type":734,"tag":1107,"props":1118,"children":1119},{},[1120],{"type":739,"value":1121},"Когда применять",{"type":734,"tag":1107,"props":1123,"children":1124},{},[1125],{"type":739,"value":1126},"Типичная ошибка",{"type":734,"tag":1128,"props":1129,"children":1130},"tbody",{},[1131,1165,1199],{"type":734,"tag":1103,"props":1132,"children":1133},{},[1134,1143,1148,1153],{"type":734,"tag":1135,"props":1136,"children":1137},"td",{},[1138],{"type":734,"tag":782,"props":1139,"children":1141},{"className":1140},[],[1142],{"type":739,"value":825},{"type":734,"tag":1135,"props":1144,"children":1145},{},[1146],{"type":739,"value":1147},"Отправка только по HTTPS",{"type":734,"tag":1135,"props":1149,"children":1150},{},[1151],{"type":739,"value":1152},"Всегда для чувствительных cookie",{"type":734,"tag":1135,"props":1154,"children":1155},{},[1156,1158,1163],{"type":739,"value":1157},"Оставлять без ",{"type":734,"tag":782,"props":1159,"children":1161},{"className":1160},[],[1162],{"type":739,"value":825},{"type":739,"value":1164}," на HTTPS-сайте",{"type":734,"tag":1103,"props":1166,"children":1167},{},[1168,1176,1189,1194],{"type":734,"tag":1135,"props":1169,"children":1170},{},[1171],{"type":734,"tag":782,"props":1172,"children":1174},{"className":1173},[],[1175],{"type":739,"value":832},{"type":734,"tag":1135,"props":1177,"children":1178},{},[1179,1181,1187],{"type":739,"value":1180},"Запрет доступа из JavaScript (",{"type":734,"tag":782,"props":1182,"children":1184},{"className":1183},[],[1185],{"type":739,"value":1186},"document.cookie",{"type":739,"value":1188},")",{"type":734,"tag":1135,"props":1190,"children":1191},{},[1192],{"type":739,"value":1193},"Для сессионных идентификаторов",{"type":734,"tag":1135,"props":1195,"children":1196},{},[1197],{"type":739,"value":1198},"Пытаться читать такую cookie на клиенте",{"type":734,"tag":1103,"props":1200,"children":1201},{},[1202,1211,1216,1221],{"type":734,"tag":1135,"props":1203,"children":1204},{},[1205],{"type":734,"tag":782,"props":1206,"children":1208},{"className":1207},[],[1209],{"type":739,"value":1210},"SameSite=Lax/Strict/None",{"type":734,"tag":1135,"props":1212,"children":1213},{},[1214],{"type":739,"value":1215},"Ограничение отправки в кросс-сайт контекстах",{"type":734,"tag":1135,"props":1217,"children":1218},{},[1219],{"type":739,"value":1220},"Защита от CSRF и трекинга",{"type":734,"tag":1135,"props":1222,"children":1223},{},[1224,1226,1232,1234,1239],{"type":739,"value":1225},"Ставить ",{"type":734,"tag":782,"props":1227,"children":1229},{"className":1228},[],[1230],{"type":739,"value":1231},"SameSite=None",{"type":739,"value":1233}," без ",{"type":734,"tag":782,"props":1235,"children":1237},{"className":1236},[],[1238],{"type":739,"value":825},{"type":739,"value":1240}," (обычно блокируется)",{"type":734,"tag":735,"props":1242,"children":1243},{},[1244,1246,1251],{"type":739,"value":1245},"Пояснение по ",{"type":734,"tag":782,"props":1247,"children":1249},{"className":1248},[],[1250],{"type":739,"value":839},{"type":739,"value":1252},":",{"type":734,"tag":979,"props":1254,"children":1255},{},[1256,1267,1278],{"type":734,"tag":983,"props":1257,"children":1258},{},[1259,1265],{"type":734,"tag":782,"props":1260,"children":1262},{"className":1261},[],[1263],{"type":739,"value":1264},"Lax",{"type":739,"value":1266}," часто является разумным значением по умолчанию: cookie обычно отправляется при «безопасной» навигации верхнего уровня на сайт, но ограничивается в большинстве фоновых кросс-сайт запросов",{"type":734,"tag":983,"props":1268,"children":1269},{},[1270,1276],{"type":734,"tag":782,"props":1271,"children":1273},{"className":1272},[],[1274],{"type":739,"value":1275},"Strict",{"type":739,"value":1277}," жёстче: cookie почти не отправляется при переходах с других сайтов",{"type":734,"tag":983,"props":1279,"children":1280},{},[1281,1287,1289],{"type":734,"tag":782,"props":1282,"children":1284},{"className":1283},[],[1285],{"type":739,"value":1286},"None",{"type":739,"value":1288}," разрешает кросс-сайт отправку, но в современных браузерах обычно требует ",{"type":734,"tag":782,"props":1290,"children":1292},{"className":1291},[],[1293],{"type":739,"value":825},{"data":1295,"body":1296},{},{"type":731,"children":1297},[1298],{"type":734,"tag":735,"props":1299,"children":1300},{},[1301,1303,1308,1310,1315],{"type":739,"value":1302},"В современных браузерах распространена политика, при которой cookie без явного ",{"type":734,"tag":782,"props":1304,"children":1306},{"className":1305},[],[1307],{"type":739,"value":839},{"type":739,"value":1309}," трактуется как ",{"type":734,"tag":782,"props":1311,"children":1313},{"className":1312},[],[1314],{"type":739,"value":1264},{"type":739,"value":1316}," (поведение зависит от браузера и версии).",{"data":1318,"body":1319},{},{"type":731,"children":1320},[1321,1326,1412,1423],{"type":734,"tag":735,"props":1322,"children":1323},{},[1324],{"type":739,"value":1325},"В условиях ужесточения приватности появились механизмы, ограничивающие «третьесторонние» cookie и трекинг, а также добавляющие более точные правила хранения.",{"type":734,"tag":979,"props":1327,"children":1328},{},[1329,1340,1360,1393],{"type":734,"tag":983,"props":1330,"children":1331},{},[1332,1338],{"type":734,"tag":782,"props":1333,"children":1335},{"className":1334},[],[1336],{"type":739,"value":1337},"Partitioned",{"type":739,"value":1339}," (CHIPS) позволяет хранить cookie в «разделённом» виде по верхнему сайту (top-level site), что полезно для встраиваемых виджетов и авторизации в iframe при минимизации трекинга",{"type":734,"tag":983,"props":1341,"children":1342},{},[1343,1345,1351,1353,1358],{"type":739,"value":1344},"Префикс ",{"type":734,"tag":782,"props":1346,"children":1348},{"className":1347},[],[1349],{"type":739,"value":1350},"__Secure-",{"type":739,"value":1352}," требует наличия ",{"type":734,"tag":782,"props":1354,"children":1356},{"className":1355},[],[1357],{"type":739,"value":825},{"type":739,"value":1359}," и установки по HTTPS",{"type":734,"tag":983,"props":1361,"children":1362},{},[1363,1364,1370,1372,1377,1379,1384,1385,1391],{"type":739,"value":1344},{"type":734,"tag":782,"props":1365,"children":1367},{"className":1366},[],[1368],{"type":739,"value":1369},"__Host-",{"type":739,"value":1371}," обычно требует ",{"type":734,"tag":782,"props":1373,"children":1375},{"className":1374},[],[1376],{"type":739,"value":825},{"type":739,"value":1378},", установки по HTTPS, отсутствия ",{"type":734,"tag":782,"props":1380,"children":1382},{"className":1381},[],[1383],{"type":739,"value":803},{"type":739,"value":789},{"type":734,"tag":782,"props":1386,"children":1388},{"className":1387},[],[1389],{"type":739,"value":1390},"Path=/",{"type":739,"value":1392},", что уменьшает риск подмены области видимости",{"type":734,"tag":983,"props":1394,"children":1395},{},[1396,1402,1404,1410],{"type":734,"tag":782,"props":1397,"children":1399},{"className":1398},[],[1400],{"type":739,"value":1401},"Priority",{"type":739,"value":1403}," (например ",{"type":734,"tag":782,"props":1405,"children":1407},{"className":1406},[],[1408],{"type":739,"value":1409},"Priority=High",{"type":739,"value":1411},") может влиять на то, какие cookie будут удержаны при переполнении лимитов",{"type":734,"tag":735,"props":1413,"children":1414},{},[1415,1417,1422],{"type":739,"value":1416},"Пример с префиксом ",{"type":734,"tag":782,"props":1418,"children":1420},{"className":1419},[],[1421],{"type":739,"value":1369},{"type":739,"value":1252},{"type":734,"tag":908,"props":1424,"children":1427},{"className":1425,"code":1426,"language":739},[911],"Set-Cookie: __Host-session=abc123; Path=/; Secure; HttpOnly; SameSite=Lax\n",[1428],{"type":734,"tag":782,"props":1429,"children":1430},{"__ignoreMap":916},[1431],{"type":739,"value":1426},{"data":1433,"body":1434},{},{"type":731,"children":1435},[1436],{"type":734,"tag":735,"props":1437,"children":1438},{},[1439,1441,1446],{"type":739,"value":1440},"Поддержка и детали ",{"type":734,"tag":782,"props":1442,"children":1444},{"className":1443},[],[1445],{"type":739,"value":1337},{"type":739,"value":1447}," и политики вокруг третьесторонних cookie зависят от браузера; архитектуру аутентификации для встроенных контекстов следует проектировать с учётом этих различий.",{"data":1449,"body":1450},{},{"type":731,"children":1451},[1452,1457,1462,1617],{"type":734,"tag":735,"props":1453,"children":1454},{},[1455],{"type":739,"value":1456},"Cookie — не единственный способ хранить состояние, и часто не самый удобный для данных, которые нужны именно JavaScript-коду.",{"type":734,"tag":735,"props":1458,"children":1459},{},[1460],{"type":739,"value":1461},"Сравнение:",{"type":734,"tag":1095,"props":1463,"children":1464},{},[1465,1496],{"type":734,"tag":1099,"props":1466,"children":1467},{},[1468],{"type":734,"tag":1103,"props":1469,"children":1470},{},[1471,1476,1481,1486,1491],{"type":734,"tag":1107,"props":1472,"children":1473},{},[1474],{"type":739,"value":1475},"Механизм",{"type":734,"tag":1107,"props":1477,"children":1478},{},[1479],{"type":739,"value":1480},"Авто-отправка на сервер",{"type":734,"tag":1107,"props":1482,"children":1483},{},[1484],{"type":739,"value":1485},"Доступ из JS",{"type":734,"tag":1107,"props":1487,"children":1488},{},[1489],{"type":739,"value":1490},"Типичный объём",{"type":734,"tag":1107,"props":1492,"children":1493},{},[1494],{"type":739,"value":1495},"Основные кейсы",{"type":734,"tag":1128,"props":1497,"children":1498},{},[1499,1531,1562,1591],{"type":734,"tag":1103,"props":1500,"children":1501},{},[1502,1506,1511,1521,1526],{"type":734,"tag":1135,"props":1503,"children":1504},{},[1505],{"type":739,"value":795},{"type":734,"tag":1135,"props":1507,"children":1508},{},[1509],{"type":739,"value":1510},"Да",{"type":734,"tag":1135,"props":1512,"children":1513},{},[1514,1516],{"type":739,"value":1515},"Да, кроме ",{"type":734,"tag":782,"props":1517,"children":1519},{"className":1518},[],[1520],{"type":739,"value":832},{"type":734,"tag":1135,"props":1522,"children":1523},{},[1524],{"type":739,"value":1525},"Небольшой",{"type":734,"tag":1135,"props":1527,"children":1528},{},[1529],{"type":739,"value":1530},"Сессии, флаги, совместимость с HTTP",{"type":734,"tag":1103,"props":1532,"children":1533},{},[1534,1543,1548,1552,1557],{"type":734,"tag":1135,"props":1535,"children":1536},{},[1537],{"type":734,"tag":782,"props":1538,"children":1540},{"className":1539},[],[1541],{"type":739,"value":1542},"localStorage",{"type":734,"tag":1135,"props":1544,"children":1545},{},[1546],{"type":739,"value":1547},"Нет",{"type":734,"tag":1135,"props":1549,"children":1550},{},[1551],{"type":739,"value":1510},{"type":734,"tag":1135,"props":1553,"children":1554},{},[1555],{"type":739,"value":1556},"Больше, чем cookie",{"type":734,"tag":1135,"props":1558,"children":1559},{},[1560],{"type":739,"value":1561},"Настройки UI, кэш состояния",{"type":734,"tag":1103,"props":1563,"children":1564},{},[1565,1574,1578,1582,1586],{"type":734,"tag":1135,"props":1566,"children":1567},{},[1568],{"type":734,"tag":782,"props":1569,"children":1571},{"className":1570},[],[1572],{"type":739,"value":1573},"sessionStorage",{"type":734,"tag":1135,"props":1575,"children":1576},{},[1577],{"type":739,"value":1547},{"type":734,"tag":1135,"props":1579,"children":1580},{},[1581],{"type":739,"value":1510},{"type":734,"tag":1135,"props":1583,"children":1584},{},[1585],{"type":739,"value":1556},{"type":734,"tag":1135,"props":1587,"children":1588},{},[1589],{"type":739,"value":1590},"Данные в рамках вкладки",{"type":734,"tag":1103,"props":1592,"children":1593},{},[1594,1599,1603,1607,1612],{"type":734,"tag":1135,"props":1595,"children":1596},{},[1597],{"type":739,"value":1598},"IndexedDB",{"type":734,"tag":1135,"props":1600,"children":1601},{},[1602],{"type":739,"value":1547},{"type":734,"tag":1135,"props":1604,"children":1605},{},[1606],{"type":739,"value":1510},{"type":734,"tag":1135,"props":1608,"children":1609},{},[1610],{"type":739,"value":1611},"Значительно больше",{"type":734,"tag":1135,"props":1613,"children":1614},{},[1615],{"type":739,"value":1616},"Офлайн-данные, сложные структуры",{"type":734,"tag":735,"props":1618,"children":1619},{},[1620,1622,1627],{"type":739,"value":1621},"Обычно идентификатор сессии хранится в cookie (часто ",{"type":734,"tag":782,"props":1623,"children":1625},{"className":1624},[],[1626],{"type":739,"value":832},{"type":739,"value":1628},"), а сами пользовательские данные и состояние — на сервере или в других хранилищах, чтобы не увеличивать трафик и не повышать риск утечек.",{"data":1630,"body":1631},{},{"type":731,"children":1632},[1633],{"type":734,"tag":979,"props":1634,"children":1635},{},[1636,1649,1654,1659],{"type":734,"tag":983,"props":1637,"children":1638},{},[1639,1641,1647],{"type":739,"value":1640},"Сессии: cookie хранит идентификатор ",{"type":734,"tag":782,"props":1642,"children":1644},{"className":1643},[],[1645],{"type":739,"value":1646},"session_id",{"type":739,"value":1648},", сервер хранит состояние сессии и связывает его с пользователем",{"type":734,"tag":983,"props":1650,"children":1651},{},[1652],{"type":739,"value":1653},"Персонализация: язык, тема, экспериментальные флаги, если нет чувствительных данных и размер мал",{"type":734,"tag":983,"props":1655,"children":1656},{},[1657],{"type":739,"value":1658},"Безопасность: CSRF-токены иногда хранятся в cookie (в зависимости от паттерна), но важно понимать модель угроз и наличие XSS-защиты",{"type":734,"tag":983,"props":1660,"children":1661},{},[1662],{"type":739,"value":1663},"Аналитика: исторически широко применялись третьесторонние cookie, но эта область активно ограничивается политиками приватности браузеров",{"data":1665,"body":1666},{},{"type":731,"children":1667},[1668,1673],{"type":734,"tag":735,"props":1669,"children":1670},{},[1671],{"type":739,"value":1672},"Основные угрозы и меры:",{"type":734,"tag":979,"props":1674,"children":1675},{},[1676,1702,1730],{"type":734,"tag":983,"props":1677,"children":1678},{},[1679,1681,1686,1688,1693,1695,1700],{"type":739,"value":1680},"XSS: при успешной инъекции скрипта злоумышленник может прочитать не-",{"type":734,"tag":782,"props":1682,"children":1684},{"className":1683},[],[1685],{"type":739,"value":832},{"type":739,"value":1687}," cookie через ",{"type":734,"tag":782,"props":1689,"children":1691},{"className":1690},[],[1692],{"type":739,"value":1186},{"type":739,"value":1694},"; снижение риска достигается ",{"type":734,"tag":782,"props":1696,"children":1698},{"className":1697},[],[1699],{"type":739,"value":832},{"type":739,"value":1701}," для сессионных cookie, строгим CSP, экранированием/валидацией ввода, безопасной генерацией HTML",{"type":734,"tag":983,"props":1703,"children":1704},{},[1705,1707,1713,1715,1721,1722,1728],{"type":739,"value":1706},"CSRF: браузер может автоматически отправить cookie на целевой сайт при кросс-сайт запросе; снижение риска достигается ",{"type":734,"tag":782,"props":1708,"children":1710},{"className":1709},[],[1711],{"type":739,"value":1712},"SameSite=Lax/Strict",{"type":739,"value":1714},", проверкой CSRF-токенов, проверкой ",{"type":734,"tag":782,"props":1716,"children":1718},{"className":1717},[],[1719],{"type":739,"value":1720},"Origin",{"type":739,"value":1058},{"type":734,"tag":782,"props":1723,"children":1725},{"className":1724},[],[1726],{"type":739,"value":1727},"Referer",{"type":739,"value":1729}," там, где уместно",{"type":734,"tag":983,"props":1731,"children":1732},{},[1733,1735,1740],{"type":739,"value":1734},"Фиксация сессии: навязывание жертве известного ",{"type":734,"tag":782,"props":1736,"children":1738},{"className":1737},[],[1739],{"type":739,"value":1646},{"type":739,"value":1741},"; снижение риска достигается регенерацией идентификатора после логина и привязкой к контексту",{"data":1743,"body":1744},{},{"type":731,"children":1745},[1746],{"type":734,"tag":735,"props":1747,"children":1748},{},[1749],{"type":739,"value":87},{"data":1751,"body":1752},{},{"type":731,"children":1753},[1754,1766,1771,1780],{"type":734,"tag":735,"props":1755,"children":1756},{},[1757,1759,1764],{"type":739,"value":1758},"Установка cookie из JavaScript возможна, но без доступа к флагу ",{"type":734,"tag":782,"props":1760,"children":1762},{"className":1761},[],[1763],{"type":739,"value":832},{"type":739,"value":1765}," и с ограничениями на некоторые атрибуты.",{"type":734,"tag":735,"props":1767,"children":1768},{},[1769],{"type":739,"value":1770},"Пример чтения и записи:",{"type":734,"tag":908,"props":1772,"children":1775},{"className":1773,"code":1774,"language":739},[911],"// Запись (часть атрибутов задаётся строкой)\ndocument.cookie = `theme=dark; Path=/; Max-Age=2592000; SameSite=Lax; Secure`;\n\n// Чтение всех доступных cookie (HttpOnly сюда не попадёт)\nconst all = document.cookie; // строка вида \"a=1; b=2\"\nconst theme = all\n  .split('; ')\n  .find(part => part.startsWith('theme='))\n  ?.split('=')[1];\n",[1776],{"type":734,"tag":782,"props":1777,"children":1778},{"__ignoreMap":916},[1779],{"type":739,"value":1774},{"type":734,"tag":735,"props":1781,"children":1782},{},[1783,1785,1790,1792,1798,1800,1806],{"type":739,"value":1784},"Важно учитывать, что ",{"type":734,"tag":782,"props":1786,"children":1788},{"className":1787},[],[1789],{"type":739,"value":1186},{"type":739,"value":1791}," работает со строками и требует аккуратного парсинга и кодирования значений, например через ",{"type":734,"tag":782,"props":1793,"children":1795},{"className":1794},[],[1796],{"type":739,"value":1797},"encodeURIComponent(...)",{"type":739,"value":1799}," при записи и ",{"type":734,"tag":782,"props":1801,"children":1803},{"className":1802},[],[1804],{"type":739,"value":1805},"decodeURIComponent(...)",{"type":739,"value":1807}," при чтении.",{"data":1809,"body":1810},{},{"type":731,"children":1811},[1812,1817,1822,1831],{"type":734,"tag":735,"props":1813,"children":1814},{},[1815],{"type":739,"value":1816},"На сервере cookie обычно устанавливается вместе с логикой сессий.",{"type":734,"tag":735,"props":1818,"children":1819},{},[1820],{"type":739,"value":1821},"Пример на Node.js (HTTP):",{"type":734,"tag":908,"props":1823,"children":1826},{"className":1824,"code":1825,"language":739},[911],"import http from 'node:http';\n\nconst server = http.createServer((req, res) => {\n  if (req.url === '/login') {\n    // Обычно тут создаётся сессия на сервере и генерируется идентификатор\n    const sid = 'abc123';\n\n    res.setHeader('Set-Cookie', [\n      `session_id=${sid}; Path=/; HttpOnly; Secure; SameSite=Lax; Max-Age=3600`,\n    ]);\n    res.statusCode = 200;\n    res.end('ok');\n    return;\n  }\n\n  const cookieHeader = req.headers.cookie ?? '';\n  res.statusCode = 200;\n  res.end(`cookies: ${cookieHeader}`);\n});\n\nserver.listen(3000);\n",[1827],{"type":734,"tag":782,"props":1828,"children":1829},{"__ignoreMap":916},[1830],{"type":739,"value":1825},{"type":734,"tag":735,"props":1832,"children":1833},{},[1834],{"type":739,"value":1835},"На практике идентификатор сессии должен быть непредсказуемым (криптографически стойким), а сервер должен проверять срок жизни, привязки и права доступа.",{"data":1837,"body":1838},{},{"type":731,"children":1839},[1840],{"type":734,"tag":735,"props":1841,"children":1842},{},[1843],{"type":739,"value":104},1775735659919]