По вашему запросу ничего не найдено :(
Убедитесь, что запрос написан правильно, или посмотрите другие наши статьи:
img
Если вас удивляет то, каким образом веб-приложения могут взаимодействовать друг с другом и передавать информацию для оптимизации операций, то вам следует познакомиться с Webhook , веб-перехватчиком. Webhook (он же веб-перехватчик) – это больше, чем просто средство информационного взаимодействия для онлайн-сервисов. Webhook – это достаточно любопытная технология, используемая для запуска приложений. Эта статья позволит получить четкое понимание того, что же такое Webhook и какие методы его работы существуют. Видео: что такое Webhook и чем отличается от API? Что такое Webhook: быстрый экскурс Webhook – это автоматически сгенерированный HTTP-запрос, созданный на основе каких-то данных. Он запускается предопределенным событием или действием в исходной системе и передается системе, с которой исходная система пытается установить связь. Webhook работает быстрее, чем опрос или API. Вместе с этим для разработчиков он является менее трудоемким с точки зрения работы. Применительно к приложениям, Webhook – это не что иное, как SMS-уведомления, которые мы получаем во время использования приложения. Например, при покупке некого товара в Интернете продавец присылает вам уведомление по SMS. Аналогично, каждый раз, когда в исходной системе происходит некоторое событие/действие, система принимающей стороны уведомляется через Webhook. Для чего нужен Webhook? Webhook используется для связи приложений и быстрого обмена данными между системой-источником и системой-получателем. Это приводит к двусторонней связи между двумя различными сетевыми системами. Ниже приведен список нескольких сценариев, при который Webhook справится лучше, чем любое другое средство связи приложений: Использование Webhook для передачи информации о событиях в различные базы данных. Требуется мгновенный ответ приложения при выполнении определенного действия. Использование Webhook для беспрепятственной синхронизации данных клиентов в приложении. Необходимость иметь модель push-уведомлений для получения своевременных обновлений. Связь должна быть взаимно-однозначной. Webhook может помочь установить соединение между средством массовой email-рассылки/управления проводимыми акциями и платежными системами. Разработчики требуют приравнять 2 системы к временной системе связи. Принимая во внимание все эти утилиты, Webhook можно назвать ключевым инструментом для разработки SaaS-приложений. Одним из реально существующих примеров использования Webhook является Shopify , который использует веб-перехватчик, например, для операций автоматического обновления корзины или объявления о продаже. Еще одной известной платформой является Stripe . Она использует Webhook для передачи сведений, связанных с обновлениями учетных записей, уведомлений об оплате и др.   Webhook vs API Человеку, не являющемуся специалистом в данной области, может показаться, что Webhook и API это одно и то же, поскольку они оба используются для установки связи между приложениями. Ситуация усугубляется, когда некоторые разработчики называют Webhook обратным API . В данном случае только опытный разработчик сможет понять разницу между этими двумя технологиями и использовать их. Мы подготовили краткий обзор основных различий между Webhook и API. Обе эти технологии, как принято считать, используются приложениями для передачи информации другому приложению. В общих чертах они работают одинаково. Ключевое различие заключается в процессе получения данных. API использует процесс «опроса» для получения необходимых данных. Опрос ( polling ) – это выполнение запросов на сервер с целью проверки появления новых данных. Webhook работает по принципу «принудительной отправки данных», то есть как только происходит инициирующее событие, из источника отправляются необходимые данные. API ожидает появления новых данных и требует периодической активности, в то время как Webhook активируется автоматически при возникновении события. Если говорить об их практической реализации, то они принципиально разные. Например, API связывается с продавцом, чтобы удостовериться, что нужный вам товар есть в наличии, а Webhook попросит продавца самому связаться с вами, как только нужный товар будет доступен. При таком подходе обе стороны экономят время и усилия. Безопасность Web API – сложная задача, поскольку запросы выполняются снова и снова, и каждый раз необходимо внедрять методы обеспечения безопасности API. Обеспечить безопасность Webhook относительно просто, поскольку запросы производятся не так часто. Webhook лучше использовать, когда требуются обновления приложения в режиме реального времени, а API – когда часто обновляется серверное приложение. Webhook – это простейшая модель API. API – это полноценный язык приложений, способный выполнять добавление, удаление и извлечение данных. Webhook работает автоматически, в то время как API требует некоторых усилий разработчика. Webhook не является широко поддерживаемым, в то время как большинство сторонних интеграций принимают API.   Как работает Webhook? На первый взгляд все кажется похожим, но Webhook включает в себя определённый сложный процесс. Вот как это работает: Шаг 1: Генерация запроса Для использования Webhook система должна быть достаточно оборудована для поддержки всего процесса. Можно разработать дружественную к Webhook систему, осуществляя несколько HTTP-запросов для различных событий. Основанный на этом принципе Webhook имеет хорошую совместимость с платформой SaaS, поскольку присутствует поддержка нескольких событий. Также с Webhook совместимы такие платформы, как GitHub, Shopify, Twilio, Stripe и Slack. Для начала нужно зарегистрироваться, чтобы принять Webhook'и. Регистрация должна быть проведена для более чем одного события. После регистрации на целевой URL будет автоматически сгенерирован запрос Webhook. Этот запрос обработается автоматически, когда произойдет определенное событие. Шаг 2: Применение Webhook Когда процесс подготовки завершен, можно использовать Webhook'и. Процесс можно упростить, если вы создадите свои Webhook и протестируете их на пригодность. Если вам покажется это слишком тяжелым, то вы можете просто добавить нужный URL-адрес веб-перехватчика в приложение и начать делиться данными. Для использования Webhook вы можете использовать средства, указанные ниже: 1. RequestBin и Postman для тестирования Webhook Как уже отмечалось, тестирование Webhook – это наиболее эффективный способ понять его метод работы. RequestBin и Postman – два самых популярный инструмента для тестирования. Используя RequestBin, разработчики могут создавать нужные URL-адреса веб-перехватчиков и обмениваться данными, чтобы проверить, как он их идентифицирует. Postman аналогично может обрабатывать процесс отправки запроса для терминала и выделенный код приложения. Разработчик может свободно работать с кодировкой JSON и XML. 2. Общение приложений Тестирование Webhook было исчерпывающим. И теперь можно приступить к делу и позволить приложениям общаться между собой. Для начала разработчикам необходимо активировать Webhook триггерных приложений. Как правило, каждое приложение имеет большое количество настроек веб-перехватчиков. Чтобы получить данные из используемого триггерного приложения, необходимо открыть настройку Webhook в заданной форме. Будет сгенерировано поле URL и варианты для спецификации HTTP-запроса веб-перехватчика. На следующем шаге уже необходимо использовать URL-адреса приложения, получающего данные. В этом приложении каждый документ имеет свой конкретный URL-адрес слияния. Скопируйте URL-адрес слияния или любой другой предполагаемый URL-адрес приложения. Затем снова перейдите в приложение-триггер и вставьте скопированный URL-адрес веб-перехватчика из приложения, получающего данные, в поле URL-адреса приложения-триггера. Сохраните изменения. Теперь приложение готово к работе. Вы можете использовать любой из вышеупомянутых средств включения Webhook. Чтобы концепция работы была более понятна, ниже мы привели пример работы Webhook Shopify:   Пример Webhook Давайте продолжим приведенный выше пример Shopify. Предположим, что новый пользователь только что разместил 2 заказа в интернет-магазине после подтверждения адреса электронной почты. Получение информации с помощью события customer/update будет выглядеть примерно так: HTTP/1.1 200 OK { "webhook": { "id": 744408886555322224, "email": "ss@testmail.com", "accepts_marketing": false, "created_at": null, "updated_at": null, "first_name": "Jane", "last_name": "Doe", "orders_count": 2, "state": "disabled", "total_spent": "0.00", "last_order_id": 54254, 54258 "note": "The user registered from India and uses store for sending gifts", "verified_email": true, "multipass_identifier": null, "tax_exempt": false, "phone": 8585858585, "tags": "retailer", "last_order_name": null, "currency": "INR", "addresses": [ ], "accepts_marketing_updated_at": null, "marketing_opt_in_level": null, "admin_graphql_api_id": "gid://shopify/Customer/744408886555322224" } } Заключение Процесс передачи данных является ключевым во взаимодействии человека и веб-приложений. Webhook делает взаимодействие между приложениями быстрым, беспрепятственным и не таким сложным. Webhook является альтернативой API и автоматизирует коммуникационное соединение.
img
SNMP (Simple Network Management Protocol) - стандартный протокол для запроса информации о состоянии сетевых устройств, и он является pull протоколом - это означает, что SNMP обязан на регулярной основе запрашивать информацию о состоянии устройств - SNMP-коллекторы опрашивают устройства, а SNMP-агенты на устройствах передают данную информацию. Частота опросов основывается на нескольких факторах, таких как: Степень необходимой детализации получаемой информации; Объем доступного места на хранилище; Срок хранения данной информации; SNMP является широко распространенным протоколом - в свободном доступе находится как достаточно много решений-коллекторов с открытым кодом, так и коммерческих вариантов - причем существуют как программные решения, так и “железные”. Маршрутизаторы и свичи чаще всего являются SNMP-агентами, также как и три основных операционных системы - Windows, Mac OS и Linux. Но с небольшой поправкой, на них SNMP служба должна быть запущена вручную. Важно: SNMP может предоставить много полезной информации о “здоровье” оборудования, но необходимо помнить, что всегда нужно использовать безопасную версию SNMP протокола - с настроенной аутентификацией и нестандартной Community строкой. Версии SNMP протокола Всего существует три основных (они же и повсеместно используемые) версии SNMP протокола, в нашем случае мы будем использовать третью версию. Ниже, на всякий случай, приведено краткое описание каждой из версий. SNMP v1 Первая версия является оригинальной версией и до сих пор используется, даже практически спустя тридцать лет. В данной версии нельзя применить никакие меры для повышения безопасности помимо Community строки, которая является чем-то вроде пароля. Если данная строка на Коллекторе соответствует строке на Агенте, то Коллектор сможет запросить информацию. Именно поэтому так важно изолировать SNMP и поместить его в отдельную подсеть и изменить Community строку. SNMP v2c Версия 2с привнесла дополнительные фичи в SNMP, но основным инструментом повышения безопасности все еще является Community строка. Следующая версия (v3) является предпочтительным вариантом, но некоторые организации все еще используют v1 и v2c. SNMP v3 Третья версия имеет в себе фичи шифрования и аутентификации, а также способна отправлять настройки на удаленные SNMP-агенты. Данная версия является предпочтительной, но необходимо чтобы и Коллектор, и Агент поддерживали её. Несмотря на то, что SNMP v3 позволяет удаленно конфигурировать девайсы, большинство организаций не используют данную фичу - для этих целей используются такие решения как Ansible, Puppet, Chef или проприетарные системы управления. Настройка на маршрутизаторе MikroTik На большинстве устройств Community строкой является слово “public” - и этот факт широко известен, к примеру порт сканнер Nmap автоматически будет пробовать данный вариант. Если данная строка не была изменена, вы, по сути, предоставляете очевидную лазейку злоумышленникам. К сожалению, на маршрутизаторах MikroTik данную строку нельзя отключить или удалить, но её можно изменить и запретить. /snmp community set 0 name=not_public read-access=no write-access=no Затем необходимо создать SNMP Community со следующими параметрами: Нестандартное имя; Только чтение; Аутентификация; Шифрование; Для этого можно использовать команду ниже - она сделает все необходимое, но, естественно, вам необходимо поменять строки wow_password и awesome_password на актуальные пароли, которые будут использоваться у вас в системе. Также поменяйте имя строки на любое другое - в примере используется имя perch_pike. /snmp community add name=perch_pike read-access=yes write-access=no authentication-protocol=SHA1 authentication-password=wow_password encryption-protocol=AES encryption-password=awesome_password security=private Осталось выполнить всего одну команду для включения SNMP и настройки вашей локации и контактной информации для устройства: /snmp set contact="Aristarh @ Merion Networks" location="Internet, RUS" enabled=yes Заключение SNMP - широко известный протокол, который также хорошо поддерживается компанией MikroTik и остальными производителями. Всегда используйте нестандартные Community строки, аутентификацию и шифрование, чтобы быть на 100% уверенными в том, что злоумышленники не могут получить информацию об устройствах в вашей сети - и тогда SNMP будет верным помощником в поддержке вашей сети.
img
Что такое DOM? DOM (Document Object Model) – это объектная модель документа. Это интерфейс между JavaScript и веб-браузером.  С помощью DOM вы можете написать код JavaScript для создания, изменения или удаления элементов HTML, установки стилей, классов и атрибутов, а также для принятия событий и реагирования на них. Дерево DOM формируется из HTML-документа, и с ним уже можно будет взаимодействовать. DOM – это очень сложный API, у которого есть методы и свойства для взаимодействия с деревом DOM. Как работает DOM – за кадром DOM продуманно организован. Родительский элемент называется EventTarget. Приведенная ниже диаграмма поможет вам лучше понять, как это работает: EventTarget – это интерфейс, реализуемый объектами, которые могут принимать события и у которых могут быть обработчики этих событий. Иными словами, любой источник событий реализует три метода, которые связаны с этим интерфейсом. Самыми распространенными генераторами событий являются Element и его дочерние элементы, Document и Window. Другие объекты также могут выступать в качестве источников событий.  Объект Window - это окно браузера. Все глобальные объекты, функции и переменные JavaScript автоматически становятся частью объекта Window. Глобальные переменные – это свойства Window. Глобальные функции – это методы Window. И даже Document (DOM HTML) является свойством Window. window.document.getElementById("header"); // Both are same document.getElementById("header"); В модели дом DOM есть узлы., и все части документа, такие как элементы, атрибуты, текст и т.д., организованы в виде иерархической древовидной структуры, которая состоит из родителей и потомков. Все эти части документа называются узлами (Node). Node на приведенной выше диаграмме представлен как объект JavaScript. В основном мы работаем с document, у которого есть такие распространенные методы, как document.queryselector(), document.getElementBy Id() и т.д. Теперь давайте посмотрим на document.  Как выбирать, создавать и удалять элементы с помощью DOM С помощью DOM мы можем выбирать, удалять и создавать элементы в JavaScript. Как выбирать элементы  Существует несколько способов выбрать HTML-элементы (HTML Elements) в JavaScript. Здесь мы рассмотрим следующие методы:  document.getElementById(); document.getElementByClassName(); document.getElementByTagName(); document.querySelector(); document.querySelectorAll(); Как использовать метод document.getElementById() Метод getElementById() возвращает элемент, идентификатор которого соответствует переданной строке. Идентификаторы элементов HTML должны быть уникальными, поэтому это самый быстрый способ выбрать элемент с идентификатором.  Пример: const ele = document.getElementById("IDName"); console.log(ele); // This will log the whole HTML element Как использовать метод document.getElementByClassName() Метод document.getElementByClassName() возвращает HTMLCollection элементов, которые соответствуют имени переданного класса. Можно искать сразу несколько имен классов, передав их через пробел. Тогда этот метод вернет «живую» HTMLCollection. Что такое «живая» HTMLCollection? Это означает, что как только мы получим HTMLCollection для какого-то имени класса, и если мы добавим элемент с тем же именем класса, то HTMLCollection автоматически обновится.  Пример: const ele = document.getElementByClassName("ClassName"); console.log(ele); // Logs Live HTMLCollection Как использовать метод document.getElementByTagName() Метод document.getElementByTagName() возвращает HTMLCollection элементов, которые соответствуют переданному имени тега. Его можно вызывать для любого элемента HTML. Метод вернет «живую» HTMLCollection. Пример: const paragraph = document.getElementByTagName("p"); const heading = document.getElementByTagName("h1"); console.log(paragraph); // p element HTMLCollection console.log(heading); // h1 element HTMLCollection   Как использовать метод document.querySelector() Метод document.querySelector() возвращает первый элемент, который соответствует переданному селектору. Здесь мы можем передать имя класса, идентификатор и имя тега. Давайте посмотрим на пример ниже: const id = document.querySelector("#idname"); // using id const classname = document.querySelector(".classname"); // using class const tag = document.querySelector("p"); // using tagname Правила выбора: если вы выбираете по имени класса, то используйте (.) в начале. Например, (“.classname”). если вы выбираете по идентификатору, то используйте (#) в начале. Например, (“#id”). если вы выбираете по имени тега, то просто введите тег. Например,  (“p”).  Как использовать метод document.querySelectorAll() Метод document.querySelectorAll() - это расширение метода querySelector. Этот метод возвращает все элементы, которые соответсвуют переданному селектору. Он возвращает «неживую» коллекцию Nodelist.  Пример: const ele = document.querySelectorAll("p"); console.log(ele); // return nodelist collection of p tag   ПРИМЕЧАНИЕ : HTMLCollection – это «живая» коллекция, а коллекция Nodelist – статическая.    Как создавать элементы Вы можете создавать HTML-элементы в JavaScript и динамически добавлять их в HTML. Вы можете создать любой элемент HTML с помощью метода document.createElement(), просто передав имя тега в скобках.    После того, как элемент будет создан, вы сможете добавить к нему имя класса, атрибуты и текст.    Вот пример: const ele = document.createElement("a"); ele.innerText = "Click Me"; ele.classList.add("text-left"); ele.setAttribute("href", "www.google.com"); // update to existing element in HTML document.querySelector(".links").prepend(ele); document.querySelector(".links").append(ele); document.querySelector(".links").befor(ele); document.querySelector(".links").after(ele); // Simalar to below anchor tag // Click Me   В приведенном выше примере мы создали тег привязки (anchor) в JavaScript и добавили атрибуты и имя класса к этому тегу. Там же у нас есть четыре метода для того, чтобы обновить созданный элемент в HTML. prepend(): вставляет данные поверх своего первого дочернего элемента. append(): вставляем данные или содержимое внутрь элемента по последнему индексу. before(): вставляет данные перед выбранным элементом. after(): помещает элемент после указанного элемента. Или можно сказать, что он вставляет данные за пределами элемента (делая это содержимое элементом того же уровня) в набор подходящих элементов. Как удалять элементы Мы знаем, как создавать элементы на JavaScript и помещать их в HTML. Но, что если нам нужно удалить элементы в HTML? Это довольно просто! Нам достаточно воспользоваться методом remove() для нужного элемента.  Вот пример: const ele = document.querySelector("p"); // This will remove ele when clicked on ele.addEventListner('click', function(){ ele.remove(); })   Как управлять CSS из JavaScript Мы знаем, как управлять HTML из JavaScript. А теперь мы узнаем, как управлять CSS из JavaScript. Это может помочь вам динамически менять стиль ваших веб-страниц.  Например, если вы нажимаете на элемент, то его фоновый цвет должен поменяться. Это реально сделать, управляя CSS из JavaScript.    Вот пример синтаксиса: const ele = document.querySelector("desired element"); ele.style.propertyName = value; // E.g - ele.style.color = red;   Когда вы меняете свойства CSS с помощью JavaScript, помните, что всякий раз, когда в CSS печатается «-», в JavaScript там будет стоять заглавная буква. Например, в CSS вы бы написали background-color, а в JavaScript – backgroundColor (с большой буквы C).    Вот пример: const ele = document.querySelector("div"); ele.style.backgroundColor = "red"; Предположим, что вы написали код CSS для своего проекта и хотите добавить классы с помощью JavaScript. Это можно сделать с помощью classList в JavaScript.    Вот еще один пример: const ele = document.querySelector(".link"); ele.classList.add("bg-red"); // add class bg-red to existing class list ele.classList.remove("pb-4");// remove class bg-red from existing class list ele.classList.toggle("bg-green"); // toggle class bg-red to existing class list which means if it already exists then it will be removed, if it doesn't exist it will be added. classList добавляет, удаляет или переключает классы относительно какого-то элемента. Это чем-то похоже на обновление существующих классов.    В отличие от element.className, он удаляет все существующие классы и добавляет указанный класс.  И еще один пример: const ele = document.querySelector(".link"); ele.classList.add("bg-red"); // add class bg-red to existing class list ele.classList.remove("pb-4");// remove class bg-red from existing class list ele.className = "p-10"; // Now this will remove all existing classes and add only "p-10 class to element."   Как использовать обработчики событий Событие (Event) – это изменение состояния объекта. Обработка событий (Event Handling) – процесс реагирования на события.  События происходит всякий раз, когда пользователь щелкает кнопкой мыши, наводит курсор на элемент, нажимает клавишу и т.д. Поэтому, когда происходит событие, и вы хотите выполнить какое-то действие, то вы используете обработчики событий, чтобы это действие произошло.  Мы используем обработчики событий для того, чтобы выполнить определенный код, когда это конкретное событие происходит. В JavaScript есть несколько обработчиков событий, однако процесс их добавления к элементам одинаков.  Вот синтаксис: const ele = document.querySelector("a"); ele.addEventListner("event", function(){ // callback function }); Вот некоторые события, которые вы можете использовать: click mouseover mouseout keypress keydown А вот пример использования события «click» (нажатия на кнопку мыши): const ele = document.querySelector("a"); ele.addEventListner("click", function(){ ele.style.backgroundColor = "pink"; }); Распространение событий: всплывание событий и перехват событий Распространение событий определяет то, в каком порядке элементы будут получать события. Существует два способа обработки порядка распространения событий в DOM: всплывание событий и перехват событий.  Что такое всплывание событий? Когда в каком-то компоненте происходит событие, то он сначала на нем запускается обработчик событий, только потом на его родительском компоненте, а затем уже и на всех остальных компонентах, которых называют предками.  По умолчанию все обработчики событий перемещаются именно в этом порядке - от события центрального компонента к событию компонента, который находится от него дальше всех.    Что такое перехват событий? Этот способ – противоположность предыдущему. Обработчик событий запускается сначала на родительском компоненте, а уже потом на том компоненте, на котором он фактически и должен был сработать.  Проще говоря, это означает, что событие сначала перехватывается самым удаленным элементом, а затем распространяется на внутренние элементы. Также этот способ называют «просачиванием вниз».    Давайте попробуем запустить следующий пример:                Example           
           
    Этот код выдаст нам следующее: Теперь давайте внимательно изучим приведенный выше пример. Я добавил получатель событий к тегу nav и тегу anchor. Когда вы нажимаете на nav, то цвет фона меняется на зеленый. Когда вы нажимаете на тег anchor, то цвет фона меняется на розовый.  Но когда вы нажимаете на тег anchor, то цвет фона меняется как у nav, так и у anchor. Это происходит из-за всплывания событий.    Вот что происходит, когда вы нажимаете только на элемент nav:       А вот что происходит, когда вы нажимаете только на элемент anchor: Для того, чтобы остановить распространение событий, мы можем воспользоваться методом stoppropagation() на получателе событий, из-за которого и происходит распространение события. В таком случае в приведенном выше примере получатель событий элемента nav не сработает.                   Example           
           
    Как перемещаться по модели DOM «Хороший разработчик JavaScript должен знать, как перемещаться по модели DOM. Перемещаться по модели DOM значит выбирать один элемент из другого,» - Зелл Лью. Теперь посмотрим, почему лучше обойти модель DOM, чем использовать метод document.querySelector(), и как это выполнить на профессиональном уровне.  Есть три способа обхода модели DOM: Снизу-вверх Сверху-вниз Продольный Как обойти модель DOM снизу-вверх Существует два метода, которые помогут вам перемещаться по модели DOM снизу-вверх: parentElement closest parentElement – это свойство, которое выбирает родительский элемент, например: const ele = document.querySelector("a"); console.log(ele.parentElement); //
parentElement отлично подходит для того, чтобы выбрать элемент, который находится на один уровень выше. Но closest позволяет найти элемент, который может быть на несколько уровней выше текущего. closest позволяет вам выбрать ближайший элемент-предок, который соответствует селектору.  Вот пример с использованием closest:
   

This is sample

   

This is heading

   

This heading 2

const ele = document.querySelector(".heading"); console.log(ele.closest(".demo")); // This is heading В приведенном выше фрагменте кода мы пытаемся получить ближайший элемент к .heading, который имеет класс .demo. Как обойти модель DOM сверху-вниз Мы можем перемещаться вниз, используя метод селектора children. При таком подходе вы можете выбрать прямого потомка нужного элемента.   Вот пример:
   Link-1    Link-2    Link-3    Link-4
const ele = document.querySelector("div"); const child = ele.children; console.log(child); // gives HTMLCollection // 4 element inside div Как обойти модель DOM продольно Это очень интересный вопрос, как же мы можем продольно обойти DOM. В основном мы можем использовать лишь два метода: previousElementSibling nextElementSibling С помощью метода previousElementSibling мы можем выбрать предшествующие элементы в HTML:
   Link-1    

Heading

const ele = document.querySelector("h1"); console.log(ele.previousElementSibling); // Link-1 А с помощью метода nextElementSibling мы можем выбрать последующие элементы в HTML:
   Link-1    

Heading

const ele = document.querySelector("a"); console.log(ele.nextElementSibling); //

Heading

ВЕСЕННИЕ СКИДКИ
40%
50%
60%
До конца акции: 30 дней 24 : 59 : 59