- Семантически корректная верстка помогает устройствам чтения с экрана и поисковым системам лучше понимать структуру и содержание веб-страницы.
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍26💊3❤1
Позволяет группировать несколько дочерних элементов без добавления дополнительного узла в DOM. Это полезно, когда вам нужно вернуть несколько элементов из компонента, но вы не хотите добавлять лишние элементы, такие как
<div>
, в структуру DOM.Фрагменты не создают дополнительных элементов в DOM, что помогает избежать ненужных вложенных структур и упрощает разметку.
Избегание дополнительных узлов может немного улучшить производительность, так как уменьшается количество элементов, которые браузер должен обрабатывать и рендерить.
Использование фрагментов делает код более семантичным и чистым, показывая, что элементы логически связаны без необходимости добавлять новый HTML-элемент.
Элемент
<div>
добавляет новый узел в DOM и используется для группировки других элементов. Это стандартный блоковый элемент в HTML, который часто используется для создания контейнеров и структурирования страницы.import React from 'react';
function List() {
return (
<React.Fragment>
<li>Элемент 1</li>
<li>Элемент 2</li>
<li>Элемент 3</li>
</React.Fragment>
);
}
// С использованием короткого синтаксиса:
function List() {
return (
<>
<li>Элемент 1</li>
<li>Элемент 2</li>
<li>Элемент 3</li>
</>
);
}
<div>
позволяет легко добавлять стили, классы и атрибуты, что делает его полезным для создания структурированных и стилизованных контейнеров.<div>
подходит для создания блоков, секций и контейнеров, которые требуют определенной разметки или стилей.import React from 'react';
function Container() {
return (
<div className="container">
<p>Это первый параграф</p>
<p>Это второй параграф</p>
</div>
);
}
Когда вам нужно вернуть несколько элементов из компонента без добавления лишних узлов в DOM.
Когда группировка элементов не требует стилизации или добавления атрибутов.
Когда вам нужно добавить стили, классы или атрибуты к контейнеру.
Когда вам нужно создать структурированный блок или секцию на странице.
Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍13❤2
- Хук может заменить методы жизненного цикла классовых компонентов для выполнения кода после каждого рендеринга.
- Принимает функцию эффекта и массив зависимостей, указывая, при изменении каких пропсов или состояний должен выполняться эффект.
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍25🔥4❤2
Это шаблон в React, который позволяет повторно использовать логику компонентов. HOC — это функция, которая принимает компонент и возвращает новый компонент с добавленной функциональностью.
HOC позволяет разделять и повторно использовать логику между разными компонентами, не дублируя код.
HOC помогает создавать более абстрактные и композиционные компоненты, что улучшает архитектуру приложения.
HOC позволяет разделять обязанности между различными компонентами, улучшая структуру и читаемость кода.
HOC создается как функция, которая принимает компонент и возвращает новый компонент с добавленной функциональностью.
В этом примере
withLogging
— это функция, которая принимает компонент WrappedComponent
и возвращает новый компонент, оборачивающий WrappedComponent
с добавленной логикой логирования.import React, { Component } from 'react';
// Функция, создающая HOC
function withLogging(WrappedComponent) {
return class extends Component {
componentDidMount() {
console.log(`Компонент ${WrappedComponent.name} был смонтирован`);
}
componentWillUnmount() {
console.log(`Компонент ${WrappedComponent.name} будет размонтирован`);
}
render() {
// Передача пропсов в обёрнутый компонент
return <WrappedComponent {...this.props} />;
}
};
}
// Пример использования HOC
class MyComponent extends Component {
render() {
return <div>Привет, мир!</div>;
}
}
const MyComponentWithLogging = withLogging(MyComponent);
export default MyComponentWithLogging;
HOC может использоваться для оборачивания компонента логикой загрузки данных из API или управления состоянием данных.
HOC может использоваться для управления доступом к компонентам, проверяя права пользователя и условно рендеря компоненты.
HOC может добавлять общие методы или состояние, которое нужно разделить между несколькими компонентами.
В этом примере
withAuthorization
проверяет роль пользователя и условно рендерит WrappedComponent
, если пользователь имеет соответствующую роль, или показывает сообщение о запрете доступа.import React from 'react';
// Функция, создающая HOC для проверки прав доступа
function withAuthorization(WrappedComponent, userRole) {
return class extends React.Component {
render() {
const { role } = this.props;
if (role !== userRole) {
return <div>Доступ запрещен</div>;
}
return <WrappedComponent {...this.props} />;
}
};
}
// Пример использования HOC
class AdminPanel extends React.Component {
render() {
return <div>Панель администратора</div>;
}
}
const AdminPanelWithAuthorization = withAuthorization(AdminPanel, 'admin');
export default AdminPanelWithAuthorization;
Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍14❤1
- DOM позволяет программам читать и изменять документ структурно, стилистически и содержательно, реагируя на пользовательские взаимодействия.
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍24🔥4❤1
Начальное состояние, не завершённое или отклонённое.
Операция завершена успешно.
Операция завершена с ошибкой.
Промис создаётся с использованием конструктора
Promise
, который принимает функцию с двумя аргументами: resolve
и reject
. Эти аргументы являются функциями, которые изменяют состояние промиса.const myPromise = new Promise((resolve, reject) => {
// Асинхронная операция
setTimeout(() => {
const success = true;
if (success) {
resolve('Операция успешно завершена');
} else {
reject('Произошла ошибка');
}
}, 1000);
});
Промисы имеют несколько методов, которые позволяют работать с результатом асинхронной операции.
Метод
then
используется для обработки успешного выполнения промиса (состояние Fulfilled). Он принимает два аргумента: первый — функция для обработки успешного результата, второй — функция для обработки ошибки (необязательный).myPromise.then(result => {
console.log(result); // 'Операция успешно завершена'
}).catch(error => {
console.error(error);
});
Метод
catch
используется для обработки отклонённого промиса (состояние Rejected). Он принимает функцию, которая будет вызвана при ошибке.myPromise.catch(error => {
console.error(error); // 'Произошла ошибка'
});
Метод
finally
выполняется после завершения промиса, независимо от того, был он исполнен или отклонён. Он полезен для выполнения кода, который должен быть выполнен в любом случае (например, очистка ресурсов).myPromise.finally(() => {
console.log('Промис завершён'); // Выполняется в любом случае
});
Методы
then
и catch
возвращают новые промисы, что позволяет создавать цепочки асинхронных операций.myPromise
.then(result => {
console.log(result); // 'Операция успешно завершена'
return 'Следующий результат';
})
.then(nextResult => {
console.log(nextResult); // 'Следующий результат'
})
.catch(error => {
console.error(error); // Обработка ошибок для всех предыдущих промисов
});
function fetchData(url) {
return new Promise((resolve, reject) => {
const xhr = new XMLHttpRequest();
xhr.open('GET', url);
xhr.onload = () => {
if (xhr.status === 200) {
resolve(JSON.parse(xhr.responseText));
} else {
reject(`Ошибка: ${xhr.status}`);
}
};
xhr.onerror = () => reject('Ошибка сети');
xhr.send();
});
}
fetchData('https://api.example.com/data')
.then(data => {
console.log('Данные получены:', data);
})
.catch(error => {
console.error('Ошибка получения данных:', error);
});
Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍35
2. Переназначение: Переменные, объявленные с помощью `let`, могут быть переназначены, т.е. вы можете изменить значение переменной позже в коде.
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍28🔥1
Forwarded from Идущий к IT
Твое резюме на HeadHunter — ОК, если ты видишь это.
HeadHunter сравнивает ключевые навыки в твоем резюме и в вакансии и в момент отклика отображает, насколько % ты соответствуешь требованиям.
Специальный бейджик «Подходит по навыкам на 100%» отображается, если соответствие составляет более 60%.
Если при просмотре вакансий ты видишь такой бейджик, это значит, что список навыков в твоем резюме качественно составлен.
Это важный параметр, так как рекрутерам чаще показываются резюме с лучшим соответствием.
О том, как правильно указывать ключевые навыки и оптимизировать свое резюме я уже рассказывал в этом видео
HeadHunter сравнивает ключевые навыки в твоем резюме и в вакансии и в момент отклика отображает, насколько % ты соответствуешь требованиям.
Специальный бейджик «Подходит по навыкам на 100%» отображается, если соответствие составляет более 60%.
Если при просмотре вакансий ты видишь такой бейджик, это значит, что список навыков в твоем резюме качественно составлен.
Это важный параметр, так как рекрутерам чаще показываются резюме с лучшим соответствием.
О том, как правильно указывать ключевые навыки и оптимизировать свое резюме я уже рассказывал в этом видео
👍2
Для обработки значений формы в Vuex (состоянии управления в приложениях Vue) нужно выполнить следующие шаги:
Создайте компонент с формой, который будет использоваться для ввода данных.
<template>
<div>
<form @submit.prevent="handleSubmit">
<label for="name">Имя:</label>
<input type="text" id="name" v-model="name" />
<label for="email">Email:</label>
<input type="email" id="email" v-model="email" />
<button type="submit">Отправить</button>
</form>
</div>
</template>
<script>
export default {
data() {
return {
name: '',
email: ''
};
},
methods: {
handleSubmit() {
this.$store.dispatch('submitForm', {
name: this.name,
email: this.email
});
}
}
};
</script>
Создайте состояние для хранения данных формы, мутации для обновления состояния и действия для обработки отправки формы.
import Vue from 'vue';
import Vuex from 'vuex';
Vue.use(Vuex);
export default new Vuex.Store({
state: {
formData: {
name: '',
email: ''
}
},
mutations: {
SET_FORM_DATA(state, payload) {
state.formData = payload;
}
},
actions: {
submitForm({ commit }, formData) {
// Здесь вы можете выполнить любые асинхронные операции, такие как отправка данных на сервер
// Например, с использованием axios:
// axios.post('/api/form', formData).then(response => {
// console.log(response.data);
// });
commit('SET_FORM_DATA', formData);
}
}
});
Вы можете использовать
mapState
и mapMutations
для связывания состояния и мутаций Vuex с вашим компонентом.<template>
<div>
<form @submit.prevent="handleSubmit">
<label for="name">Имя:</label>
<input type="text" id="name" v-model="localName" />
<label for="email">Email:</label>
<input type="email" id="email" v-model="localEmail" />
<button type="submit">Отправить</button>
</form>
</div>
</template>
<script>
import { mapState, mapActions } from 'vuex';
export default {
computed: {
...mapState({
name: state => state.formData.name,
email: state => state.formData.email
}),
localName: {
get() {
return this.name;
},
set(value) {
this.updateForm({ name: value, email: this.email });
}
},
localEmail: {
get() {
return this.email;
},
set(value) {
this.updateForm({ name: this.name, email: value });
}
}
},
methods: {
...mapActions(['submitForm']),
handleSubmit() {
this.submitForm({
name: this.localName,
email: this.localEmail
});
},
updateForm(payload) {
this.$store.commit('SET_FORM_DATA', payload);
}
}
};
</script>
Когда пользователь отправляет форму, данные формы отправляются в Vuex с помощью действия
submitForm
, которое обновляет состояние через мутацию SET_FORM_DATA
.Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍4🔥1
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
❤21👍15
Который является официальной библиотекой для управления состоянием в приложениях Vue.js,
mutations
(мутации) и actions
(действия) играют ключевые роли в управлении состоянием. Они помогают обеспечивать предсказуемость изменения состояния и организовывают логику приложения.Это единственный способ изменить состояние в Vuex. Каждая мутация имеет тип и обработчик. Обработчик мутации получает состояние как первый аргумент, и дополнительный аргумент в качестве полезной нагрузки (payload), который можно использовать для передачи данных в мутацию. Мутации должны быть синхронными, чтобы изменения состояния можно было легко отслеживать. Это помогает делать отладку и логгирование более предсказуемыми.
import Vue from 'vue';
import Vuex from 'vuex';
Vue.use(Vuex);
export default new Vuex.Store({
state: {
count: 0
},
mutations: {
increment(state) {
state.count++;
},
incrementBy(state, payload) {
state.count += payload.amount;
}
}
});
Действия используются для выполнения асинхронных операций или сложной бизнес-логики перед вызовом мутаций. Действия могут содержать произвольную асинхронную логику, такие как API-запросы, и затем вызывать мутации для изменения состояния. Действия вызываются с помощью метода
dispatch
и могут возвращать промисы, что полезно для обработки цепочек асинхронных операций.import Vue from 'vue';
import Vuex from 'vuex';
Vue.use(Vuex);
export default new Vuex.Store({
state: {
count: 0
},
mutations: {
increment(state) {
state.count++;
}
},
actions: {
incrementAsync({ commit }) {
setTimeout(() => {
commit('increment');
}, 1000);
},
incrementByAsync({ commit }, payload) {
setTimeout(() => {
commit('incrementBy', payload);
}, 1000);
}
}
});
Синхронно изменяют состояние.
Могут быть асинхронными и обычно вызывают мутации для изменения состояния.
Пример взаимодействия
// store.js
import Vue from 'vue';
import Vuex from 'vuex';
Vue.use(Vuex);
export default new Vuex.Store({
state: {
message: ''
},
mutations: {
setMessage(state, message) {
state.message = message;
}
},
actions: {
fetchMessage({ commit }) {
setTimeout(() => {
const message = 'Hello from async action!';
commit('setMessage', message);
}, 2000);
}
}
});
Компонент
<template>
<div>
<p>{{ message }}</p>
<button @click="loadMessage">Load Message</button>
</div>
</template>
<script>
import { mapState, mapActions } from 'vuex';
export default {
computed: {
...mapState(['message'])
},
methods: {
...mapActions(['fetchMessage']),
loadMessage() {
this.fetchMessage();
}
}
};
</script>
Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍11
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍19🔥6
Это протокол коммуникации, предоставляющий двусторонний, полнодуплексный канал связи между клиентом и сервером через одно соединение TCP. Он позволяет обмениваться данными в режиме реального времени, что делает его идеальным для приложений, требующих мгновенной передачи информации, таких как чаты, игры, финансовые системы и другие.
WebSockets обеспечивают полнодуплексное общение, позволяя серверу и клиенту отправлять данные друг другу в любое время.
В отличие от HTTP, где каждое запрос-ответное взаимодействие открывает и закрывает соединение, WebSocket поддерживает постоянное соединение, что позволяет мгновенно передавать данные.
WebSockets уменьшают накладные расходы на установление соединений и протоколирование запросов, что приводит к более низкой задержке и уменьшенному использованию ресурсов по сравнению с регулярными HTTP-запросами.
WebSockets поддерживают передачу не только текстовых данных, но и бинарных, что расширяет возможности их применения.
Соединение WebSocket начинается с "рукопожатия" по протоколу HTTP. Клиент отправляет запрос на установление соединения с сервером, используя заголовок
Upgrade
, чтобы переключиться с HTTP на WebSocket.Если сервер принимает запрос, он отвечает с подтверждением, и соединение переключается на протокол WebSocket. С этого момента канал связи открыт и доступен для двусторонней передачи данных.
Клиент и сервер могут обмениваться данными в любом направлении. Сообщения отправляются в рамках установленного соединения без необходимости повторного рукопожатия.
Соединение может быть закрыто любой стороной (клиентом или сервером) в любое время. Это может быть сделано по желанию или в случае ошибки.
const WebSocket = require('ws');
const server = new WebSocket.Server({ port: 8080 });
server.on('connection', (socket) => {
console.log('Client connected');
socket.on('message', (message) => {
console.log(`Received: ${message}`);
socket.send(`You said: ${message}`);
});
socket.on('close', () => {
console.log('Client disconnected');
});
});
console.log('WebSocket server is running on ws://localhost:8080');
Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍36❤1
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥13👍6❤1
Это техника, используемая для реализации связи между клиентом и сервером в веб-приложениях, чтобы поддерживать обновление данных в реальном времени. В отличие от обычных HTTP-запросов, лонг-пулинг позволяет клиенту ждать ответа от сервера дольше, что помогает уменьшить задержку при получении новых данных.
Клиент отправляет HTTP-запрос к серверу.
Сервер не отвечает сразу, а задерживает ответ до тех пор, пока не появятся новые данные или не истечет таймаут.
Когда данные становятся доступными или истекает таймаут ожидания, сервер отправляет ответ клиенту.
Клиент обрабатывает полученные данные и немедленно отправляет новый запрос к серверу для получения следующих обновлений.
Сервер на Node.js с использованием
express
const express = require('express');
const app = express();
let messages = [];
let clients = [];
// Endpoint для отправки сообщений
app.post('/messages', (req, res) => {
const message = req.body.message;
messages.push(message);
// Уведомляем всех клиентов
clients.forEach(client => client.res.json({ message }));
clients = [];
res.status(200).send('Message sent');
});
// Endpoint для получения сообщений (лонг-пулинг)
app.get('/messages', (req, res) => {
if (messages.length > 0) {
res.json({ message: messages.pop() });
} else {
clients.push({ req, res });
}
});
app.listen(3000, () => {
console.log('Server listening on port 3000');
});
Клиентский код на JavaScript
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Long Polling Example</title>
</head>
<body>
<h1>Long Polling Example</h1>
<div id="messages"></div>
<script>
function pollMessages() {
fetch('/messages')
.then(response => response.json())
.then(data => {
const messageDiv = document.createElement('div');
messageDiv.textContent = `New message: ${data.message}`;
document.getElementById('messages').appendChild(messageDiv);
pollMessages(); // Отправляем новый запрос после получения сообщения
})
.catch(error => {
console.error('Error:', error);
setTimeout(pollMessages, 5000); // Повторный запрос через 5 секунд при ошибке
});
}
// Начинаем лонг-пулинг
pollMessages();
</script>
</body>
</html>
Лонг-пулинг позволяет получать данные в реальном времени без необходимости постоянно проверять сервер с частыми запросами.
По сравнению с обычным пулингом (когда клиент постоянно отправляет запросы с фиксированным интервалом), лонг-пулинг уменьшает количество HTTP-запросов, что снижает нагрузку на сервер.
Лонг-пулинг легче внедрить и поддерживать в сравнении с более сложными технологиями, такими как WebSockets.
Хотя лонг-пулинг уменьшает задержку по сравнению с обычным пулингом, он все же может иметь небольшие задержки в зависимости от времени ожидания и частоты событий.
Держание соединений открытыми в течение длительного времени может быть ресурсоемким для сервера, особенно при большом количестве клиентов.
Лонг-пулинг менее эффективен по сравнению с WebSockets, которые предоставляют постоянное двустороннее соединение.
Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍10❤5🔥3😁2
State manager — это инструмент или библиотека для управления состоянием приложения, особенно в сложных проектах с большим количеством взаимозависимых данных. Популярные state manager’ы включают Redux, MobX и Zustand для React-приложений, обеспечивающие централизованное хранение и управление состоянием. Они помогают структурировать данные, отслеживать их изменения и синхронизировать их между компонентами.
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍22🔥8❤1
Это процесс проверки подлинности пользователя, который пытается получить доступ к системе или ресурсу. Веб-приложения и сервисы обычно используют несколько методов аутентификации для обеспечения безопасности и защиты данных.
Пользователь вводит имя пользователя и пароль, которые проверяются на сервере. Веб-сайты с формой входа, требующей логин и пароль.
После успешного входа пользователь получает токен (например, JWT), который используется для дальнейших запросов. API, использующие токены для проверки подлинности запросов.
Протокол авторизации, позволяющий сторонним приложениям получать ограниченный доступ к ресурсам пользователя без передачи пароля. Вход через Google, Facebook или другие социальные сети.
Требует два различных типа проверки (например, пароль и одноразовый код). Вход с использованием пароля и SMS-кода.
Использует биометрические данные (например, отпечатки пальцев или распознавание лиц) для проверки подлинности. Вход через Touch ID или Face ID на мобильных устройствах.
npm install express jsonwebtoken bcryptjs body-parser
const express = require('express');
const jwt = require('jsonwebtoken');
const bcrypt = require('bcryptjs');
const bodyParser = require('body-parser');
const app = express();
const PORT = 3000;
const SECRET_KEY = 'your_secret_key';
let users = []; // Для простоты используем массив в памяти
app.use(bodyParser.json());
// Регистрация пользователя
app.post('/register', async (req, res) => {
const { username, password } = req.body;
const hashedPassword = await bcrypt.hash(password, 8);
users.push({ username, password: hashedPassword });
res.status(201).send('User registered');
});
// Вход пользователя
app.post('/login', async (req, res) => {
const { username, password } = req.body;
const user = users.find(u => u.username === username);
if (!user) {
return res.status(404).send('User not found');
}
const isPasswordValid = await bcrypt.compare(password, user.password);
if (!isPasswordValid) {
return res.status(401).send('Invalid password');
}
const token = jwt.sign({ username: user.username }, SECRET_KEY, { expiresIn: '1h' });
res.json({ token });
});
// Защищенный маршрут
app.get('/protected', (req, res) => {
const token = req.headers['authorization'];
if (!token) {
return res.status(401).send('Access denied');
}
try {
const decoded = jwt.verify(token, SECRET_KEY);
res.json({ message: 'Protected content', user: decoded });
} catch (err) {
res.status(401).send('Invalid token');
}
});
app.listen(PORT, () => {
console.log(`Server is running on http://localhost:${PORT}`);
});
Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍32🔥3
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍27🔥3
GET-запросы отправляют данные через URL, который сохраняется в истории браузера. Это означает, что любой, кто имеет доступ к истории браузера, может увидеть эти данные.
Многие веб-серверы и прокси-серверы автоматически записывают URL всех запросов в свои логи. Чувствительная информация в URL будет сохранена в этих логах и может быть доступна администраторам серверов или в случае компрометации системы.
Браузеры, прокси-серверы и промежуточные серверы могут кэшировать URL-адреса GET-запросов. Это означает, что чувствительная информация может быть сохранена в кэшах и доступна при последующих обращениях.
Большинство браузеров и серверов имеют ограничения на длину URL (обычно около 2000 символов). Если данные слишком длинные, они могут быть обрезаны, что приведет к потере информации или ошибкам при обработке запроса.
Когда пользователь переходит по ссылке с одной страницы на другую, URL-адрес исходной страницы часто передается как заголовок Referer в HTTP-запросе. Это означает, что чувствительная информация в URL может быть передана сторонним сайтам.
Данные в GET-запросах передаются через URL, в то время как данные в POST-запросах передаются в теле запроса. URL более подвержены утечке, так как они часто видны в различных местах (например, в журналах серверов, истории браузера и т.д.).
Для отправки чувствительной информации лучше использовать POST-запросы, так как данные передаются в теле запроса и не сохраняются в URL.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Secure Form</title>
</head>
<body>
<form action="/submit" method="post">
<label for="username">Username:</label>
<input type="text" id="username" name="username">
<label for="password">Password:</label>
<input type="password" id="password" name="password">
<button type="submit">Submit</button>
</form>
</body>
</html>
Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍25
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍26❤2🔥1