Для реализации отношения "один ко многим" (one-to-many) в C# с использованием Entity Framework Core, нужно определить две модели, где одна модель будет содержать коллекцию объектов другой модели.
Предположим, у нас есть две модели:
Author и Book. Один автор может написать много книг, поэтому у нас будет отношение "один ко многим". public class Author
{
public int AuthorId { get; set; }
public string Name { get; set; }
// Связь один ко многим
public ICollection<Book> Books { get; set; }
}
public class Book
{
public int BookId { get; set; }
public string Title { get; set; }
public int AuthorId { get; set; }
// Навигационное свойство
public Author Author { get; set; }
}
Создаем контекст данных, который наследуется от
DbContext. using Microsoft.EntityFrameworkCore;
public class AppDbContext : DbContext
{
public DbSet<Author> Authors { get; set; }
public DbSet<Book> Books { get; set; }
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
optionsBuilder.UseSqlServer("YourConnectionStringHere");
}
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
// Настройка связи один ко многим
modelBuilder.Entity<Author>()
.HasMany(a => a.Books)
.WithOne(b => b.Author)
.HasForeignKey(b => b.AuthorId);
}
}
Для создания и применения миграций выполните следующие команды в консоли диспетчера пакетов или CLI.
Использование Package Manager Console (PMC)
Add-Migration InitialCreate
Update-Database
Использование .NET CLI
dotnet ef migrations add InitialCreate
dotnet ef database update
Теперь можно добавить данные в базу данных и протестировать отношение "один ко многим".
public class Program
{
public static void Main()
{
using (var context = new AppDbContext())
{
var author = new Author
{
Name = "George Orwell",
Books = new List<Book>
{
new Book { Title = "1984" },
new Book { Title = "Animal Farm" }
}
};
context.Authors.Add(author);
context.SaveChanges();
}
}
}
Теперь можно извлечь данные и проверить отношение.
using (var context = new AppDbContext())
{
var authors = context.Authors.Include(a => a.Books).ToList();
foreach (var author in authors)
{
Console.WriteLine($"Author: {author.Name}");
foreach (var book in author.Books)
{
Console.WriteLine($" Book: {book.Title}");
}
}
}
Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍4
readonly — это поле, значение которого можно установить только при инициализации или в конструкторе, но оно может быть вычислено во время выполнения.
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍11🔥6
Для реализации связи "многие ко многим" (many-to-many) в реляционных базах данных используется промежуточная (связующая) таблица, которая содержит внешние ключи, ссылающиеся на обе связанные таблицы. Эта промежуточная таблица позволяет управлять отношениями между записями двух таблиц.
Предположим, у нас есть две таблицы:
Students (студенты) и Courses (курсы). Один студент может быть записан на несколько курсов, и один курс может включать нескольких студентов.Таблица
Students для хранения данных о студентах. Таблица Courses для хранения данных о курсах.Таблица
StudentCourses, которая содержит внешние ключи, ссылающиеся на Students и Courses.StudentsCREATE TABLE Students (
StudentId INT PRIMARY KEY,
StudentName VARCHAR(100)
);
CoursesCREATE TABLE Courses (
CourseId INT PRIMARY KEY,
CourseName VARCHAR(100)
);
StudentCoursesCREATE TABLE StudentCourses (
StudentId INT,
CourseId INT,
PRIMARY KEY (StudentId, CourseId),
FOREIGN KEY (StudentId) REFERENCES Students(StudentId),
FOREIGN KEY (CourseId) REFERENCES Courses(CourseId)
);
Вставка данных в таблицу
Students: INSERT INTO Students (StudentId, StudentName) VALUES (1, 'John Doe');
INSERT INTO Students (StudentId, StudentName) VALUES (2, 'Jane Smith');
Вставка данных в таблицу
CoursesINSERT INTO Courses (CourseId, CourseName) VALUES (1, 'Mathematics');
INSERT INTO Courses (CourseId, CourseName) VALUES (2, 'Science');
Вставка данных в таблицу
StudentCourses (связывающая таблица): INSERT INTO StudentCourses (StudentId, CourseId) VALUES (1, 1); -- John Doe записан на Mathematics
INSERT INTO StudentCourses (StudentId, CourseId) VALUES (1, 2); -- John Doe записан на Science
INSERT INTO StudentCourses (StudentId, CourseId) VALUES (2, 1); -- Jane Smith записана на Mathematics
Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
🤔1
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍3🔥1
Связь "один к одному" (one-to-one) и связь "многие ко многим" (many-to-many) представляют разные типы логических отношений между записями в реляционных базах данных. Основные отличия между этими двумя типами связей заключаются в их природе, реализации и сценариях использования.
Каждая запись в одной таблице соответствует ровно одной записи в другой таблице. Используется для разделения информации на связанные, но отдельные части, например, для повышения безопасности или упрощения структуры данных. Можно использовать уникальный внешний ключ или один и тот же первичный ключ в обеих таблицах.
Пользователи и их профили.
Клиенты и их учетные данные.
CREATE TABLE Users (
UserId INT PRIMARY KEY,
UserName VARCHAR(100)
);
CREATE TABLE Profiles (
ProfileId INT PRIMARY KEY,
UserId INT UNIQUE,
ProfileData VARCHAR(255),
FOREIGN KEY (UserId) REFERENCES Users(UserId)
);
Каждая запись в одной таблице может соответствовать множеству записей в другой таблице, и наоборот. Используется для представления сложных взаимосвязей, таких как студенты и курсы, где каждый студент может записаться на множество курсов, и каждый курс может включать множество студентов. Требуется промежуточная (связующая) таблица, содержащая два внешних ключа, ссылающихся на связанные таблицы. Студенты и курсы. Авторы и книги. Таблицы
Students и Courses с промежуточной таблицей StudentCourses. CREATE TABLE Students (
StudentId INT PRIMARY KEY,
StudentName VARCHAR(100)
);
CREATE TABLE Courses (
CourseId INT PRIMARY KEY,
CourseName VARCHAR(100)
);
CREATE TABLE StudentCourses (
StudentId INT,
CourseId INT,
PRIMARY KEY (StudentId, CourseId),
FOREIGN KEY (StudentId) REFERENCES Students(StudentId),
FOREIGN KEY (CourseId) REFERENCES Courses(CourseId)
);
Каждая запись в одной таблице соответствует ровно одной записи в другой таблице.
Каждая запись в одной таблице может соответствовать множеству записей в другой таблице и наоборот.
Используется уникальный внешний ключ или одинаковый первичный ключ в обеих таблицах.
Требуется промежуточная таблица для хранения связей между записями.
Пользователь и его профиль, клиент и его учетные данные.
Студенты и курсы, авторы и книги.
Получение данных пользователя и его профиля
SELECT Users.UserName, Profiles.ProfileData
FROM Users
JOIN Profiles ON Users.UserId = Profiles.UserId;
Получение всех курсов, на которые записан студент
SELECT Students.StudentName, Courses.CourseName
FROM Students
JOIN StudentCourses ON Students.StudentId = StudentCourses.StudentId
JOIN Courses ON StudentCourses.CourseId = Courses.CourseId;
Получение всех студентов, записанных на определенный курс
SELECT Courses.CourseName, Students.StudentName
FROM Courses
JOIN StudentCourses ON Courses.CourseId = StudentCourses.CourseId
JOIN Students ON StudentCourses.StudentId = Students.StudentId;
Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍2
1. Как работает: GC отслеживает объекты, на которые есть активные ссылки, и удаляет те, которые недоступны.
2. Цель: предотвращение утечек памяти и избавление разработчика от необходимости вручную освобождать память.
3. GC работает асинхронно и может вызывать паузы в работе приложения, известные как "stop-the-world".
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
❤2🔥2
Наследование в объектно-ориентированном программировании, является мощным инструментом для создания иерархий классов и повторного использования кода. Однако его использование должно быть осознанным и оправданным.
Наследование используется для создания обобщенных базовых классов и специализированных производных классов.
public class Animal
{
public void Eat() { /*...*/ }
}
public class Dog : Animal
{
public void Bark() { /*...*/ }
}
Наследование позволяет повторно использовать код базового класса в производных классах, избегая дублирования.
public class Vehicle
{
public int Speed { get; set; }
public void Move() { /*...*/ }
}
public class Car : Vehicle
{
public void Honk() { /*...*/ }
}
Наследование позволяет использовать объекты производных классов через ссылки на базовые классы, обеспечивая гибкость и расширяемость кода.
public class Shape
{
public virtual void Draw() { /*...*/ }
}
public class Circle : Shape
{
public override void Draw() { /*...*/ }
}
public void DrawShape(Shape shape)
{
shape.Draw();
}
Слишком глубокие иерархии усложняют понимание и поддержку кода. В таких случаях рассмотрите использование композиции.
Интерфейсы и абстрактные классы могут обеспечить большую гибкость и возможность для реализации различных вариантов поведения.
public interface IFlyable
{
void Fly();
}
public class Bird : IFlyable
{
public void Fly() { /*...*/ }
}
Композиция может быть предпочтительнее наследования, так как позволяет более гибко комбинировать функциональности.
public class Engine
{
public void Start() { /*...*/ }
}
public class Car
{
private Engine _engine = new Engine();
public void Start() { _engine.Start(); }
}
На практике наследование может использоваться реже, чем композиция, особенно в современных подходах к проектированию, таких как микросервисы или системы, ориентированные на интерфейсы. Тем не менее, оно остается важным инструментом, особенно когда необходимо обеспечить полиморфизм или когда существуют естественные иерархии объектов.
Наследование широко используется в библиотеках и фреймворках для предоставления базовых классов, от которых пользователи могут наследовать свои классы.
public abstract class ControllerBase
{
public abstract void Execute();
}
public class HomeController : ControllerBase
{
public override void Execute() { /*...*/ }
}
Наследование полезно при моделировании реальных объектов и их иерархий.
public class Employee
{
public string Name { get; set; }
public decimal Salary { get; set; }
}
public class Manager : Employee
{
public int NumberOfSubordinates { get; set; }
}
Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
❤3👍1👾1
1. ref: позволяет передавать ссылочный тип по ссылке, чтобы изменения в методе влияли на оригинальный объект.
o Это нужно, когда требуется изменить ссылку (например, перенаправить на новый объект) внутри метода.
2. out: используется для передачи данных из метода наружу, не требуя их предварительной инициализации.
o Это упрощает возврат нескольких значений из метода через параметры, особенно для ссылочных типов.
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍2🔥1
Это два различных механизма в C# для изменения поведения методов, свойств или событий, унаследованных от базового класса.
Переопределение используется для предоставления новой реализации метода, свойства или события в производном классе, который уже был объявлен в базовом классе как
virtual, abstract или override.Ключевое слово
override.Требование
Метод базового класса должен быть объявлен с ключевым словом
virtual или abstract.public class BaseClass
{
public virtual void Display()
{
Console.WriteLine("BaseClass Display");
}
}
public class DerivedClass : BaseClass
{
public override void Display()
{
Console.WriteLine("DerivedClass Display");
}
}
Использование
BaseClass obj = new DerivedClass();
obj.Display(); // Выведет: "DerivedClass Display"
Сокрытие используется для создания новой реализации метода, свойства или события в производном классе, который уже существует в базовом классе, но без использования
virtual и override. При сокрытии используется ключевое слово new.Ключевое слово
new.Требование
Метод базового класса не обязательно должен быть объявлен с ключевым словом
virtual.public class BaseClass
{
public void Display()
{
Console.WriteLine("BaseClass Display");
}
}
public class DerivedClass : BaseClass
{
public new void Display()
{
Console.WriteLine("DerivedClass Display");
}
}
Использование
BaseClass obj1 = new BaseClass();
obj1.Display(); // Выведет: "BaseClass Display"
DerivedClass obj2 = new DerivedClass();
obj2.Display(); // Выведет: "DerivedClass Display"
BaseClass obj3 = new DerivedClass();
obj3.Display(); // Выведет: "BaseClass Display"
Переопределение: Базовый метод должен быть объявлен как virtual, abstract или override. Сокрытие: Базовый метод не обязательно должен быть виртуальным.
Переопределение: Используется ключевое слово override. Сокрытие: Используется ключевое слово new.
Переопределение: Изменяет указатель в виртуальной таблице базового класса, что позволяет полиморфизм. Сокрытие: Создает новый метод, который скрывает метод базового класса, но не изменяет виртуальную таблицу.
Переопределение: Поддерживает полиморфизм. Вызовы методов производятся на основе реального типа объекта. Сокрытие: Не поддерживает полиморфизм. Вызовы методов зависят от типа ссылки, а не от реального типа объекта.
Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍8
2. Ссылочные: классы, интерфейсы, массивы, строки.
3. Обобщённые (Generic): позволяют работать с типами данных, указанными при создании экземпляра (например, List<T>).
4. Пользовательские: структуры, перечисления (enum), типы, созданные программистом.
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍6👾1
Блок
using используется для управления временем жизни объектов, которые потребляют неуправляемые ресурсы, такие как файлы, соединения с базой данных или сетевые соединения. Основное преимущество использования блока using заключается в автоматическом освобождении этих ресурсов, что помогает предотвратить утечки ресурсов и улучшить управление памятью.Блок
using гарантирует, что метод Dispose() будет вызван автоматически, когда выполнение кода выйдет из блока using, даже если возникнет исключение. Это освобождает программиста от необходимости вручную вызывать Dispose() и уменьшает вероятность ошибок. using (StreamReader reader = new StreamReader("file.txt"))
{
string content = reader.ReadToEnd();
Console.WriteLine(content);
}
// StreamReader автоматически закрывается и освобождает ресурсы после выхода из блока using. Использование блока
using уменьшает количество необходимого кода для обеспечения правильного освобождения ресурсов. using (SqlConnection connection = new SqlConnection(connectionString))
{
connection.Open();
// Работа с базой данных
}
// SqlConnection автоматически закрывается и освобождает ресурсы после выхода из блока using.
Блок
using повышает надежность кода, так как гарантирует, что ресурсы будут освобождены даже в случае возникновения исключений. try
{
using (StreamWriter writer = new StreamWriter("file.txt"))
{
writer.WriteLine("Hello, World!");
}
}
catch (Exception ex)
{
Console.WriteLine($"Произошла ошибка: {ex.Message}");
}
// StreamWriter автоматически закрывается и освобождает ресурсы после выхода из блока using, даже если произошла ошибка.
Код, использующий блок
using, выглядит более чистым и упрощает понимание и сопровождение. using (MemoryStream memoryStream = new MemoryStream())
{
// Работа с MemoryStream
}
// MemoryStream автоматически освобождается после выхода из блока using.
Работа с файлами
using System;
using System.IO;
class Program
{
static void Main()
{
using (StreamReader reader = new StreamReader("example.txt"))
{
string content = reader.ReadToEnd();
Console.WriteLine(content);
}
// StreamReader автоматически закрывается и освобождает ресурсы после выхода из блока using.
}
}
Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍9
1. Поколения памяти: объекты делятся на поколения (0, 1, 2) для оптимизации очистки.
2. Триггер срабатывания: GC запускается при нехватке памяти или явным вызовом.
3. Сбор поколений: сначала очищаются молодые объекты (0 поколение), а затем старшие.
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
Когда браузер отправляет запрос и получает ответ от API, это включает несколько шагов, которые следуют HTTP-протоколу. Этот процесс включает в себя создание и отправку HTTP-запроса, обработку на сервере и получение HTTP-ответа.
Обычно запрос инициируется через JavaScript с использованием встроенных функций, таких как
XMLHttpRequest, fetch или сторонние библиотеки, такие как Axios. fetch('https://api.example.com/data', {
method: 'GET',
headers: {
'Content-Type': 'application/json',
'Authorization': 'Bearer token'
}
})
.then(response => response.json())
.then(data => console.log(data))
.catch(error => console.error('Error:', error));
Метод: Указывает тип запроса (например, GET, POST, PUT, DELETE). URL: Указывает на какой URL отправляется запрос. Заголовки (Headers): Включают информацию о типе содержимого, авторизации и других метаданных. Тело (Body): Содержит данные, которые отправляются с запросом (для методов POST, PUT и PATCH).
Браузер использует сетевые протоколы для отправки сформированного HTTP-запроса на указанный сервер через интернет.
Сервер получает HTTP-запрос.
Сервер обрабатывает запрос, выполняя соответствующие действия, такие как чтение данных из базы данных, выполнение логики приложения или взаимодействие с другими сервисами.
Статус код (Status Code): Указывает результат обработки запроса (например, 200 OK, 404 Not Found, 500 Internal Server Error). Заголовки (Headers): Могут включать метаданные о содержимом ответа, кэшировании и других параметрах. Тело (Body): Содержит данные, которые отправляются обратно клиенту, часто в формате JSON или XML.
HTTP/1.1 200 OK
Content-Type: application/json
Content-Length: 85
{
"id": 1,
"name": "Example",
"description": "This is an example response"
}
Браузер получает HTTP-ответ от сервера.
Статус код: Браузер или JavaScript-код проверяет статус код, чтобы определить, был ли запрос успешным. Заголовки: Заголовки могут быть использованы для получения дополнительной информации о ответе. Тело: Браузер разбирает тело ответа, если это необходимо, например, преобразует JSON-данные в объект JavaScript.
Полученные данные могут быть использованы в приложении для обновления интерфейса пользователя, хранения в локальном хранилище или выполнения других действий.
Отправка запроса
fetch('https://api.example.com/data', {
method: 'GET',
headers: {
'Content-Type': 'application/json',
'Authorization': 'Bearer token'
}
})
.then(response => {
if (!response.ok) {
throw new Error('Network response was not ok ' + response.statusText);
}
return response.json();
})
.then(data => {
console.log('Data received:', data);
// Используем данные для обновления UI или других целей
})
.catch(error => {
console.error('There has been a problem with your fetch operation:', error);
});Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍9❤1
2. Исполнительный (динамический): достигается через переопределение методов (overriding) и виртуальные функции.
3. Полиморфизм позволяет обрабатывать объекты разных типов единообразно, например, через интерфейсы.
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍3
DNS (Domain Name System) переводит доменные имена (например,
www.example.com) в IP-адреса (например, 192.0.2.1), чтобы компьютеры могли общаться. Браузер отправляет запрос к DNS-серверу.
DNS-сервер обращается к корневым, TLD и авторитетным серверам.
Авторитетный сервер возвращает IP-адрес.
Браузер использует IP-адрес для соединения с веб-сайтом.
IPv4-адрес.
IPv6-адрес.
Псевдоним.
Почтовый сервер.
Текстовые данные.
Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
❤1
2. O: Принцип открытости/закрытости (Open/Closed Principle).
3. L: Принцип подстановки Барбары Лисков (Liskov Substitution Principle).
4. I: Принцип разделения интерфейсов (Interface Segregation Principle).
5. D: Принцип инверсии зависимостей (Dependency Inversion Principle).
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍7
Маршрутизация в ASP.NET Core сопоставляет URL-запросы с контроллерами и действиями.
Определение маршрутов
public void Configure(IApplicationBuilder app)
{
app.UseRouting();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllerRoute(
name: "default",
pattern: "{controller=Home}/{action=Index}/{id?}");
});
}
Пример контроллера
public class HomeController : Controller
{
public IActionResult Index()
{
return View();
}
}
public class ProductsController : Controller
{
public IActionResult Index() => View();
public IActionResult Details(int id) => View();
}
Атрибуты маршрутизации
[Route("api/[controller]")]
public class ProductsController : Controller
{
[HttpGet("{id}")]
public IActionResult GetProduct(int id)
{
return View();
}
}Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍4
2. Усложнение взаимодействия: требуется настройка API и их маршрутизации.
3. Трудности тестирования и деплоя: распределённые системы сложнее тестировать и синхронизировать.
4. Затраты на ресурсы: каждый сервис требует выделения собственных ресурсов, что увеличивает их потребление.
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍2🔥1
HTTP-запросы делятся на несколько типов, каждый из которых предназначен для выполнения определенных операций. Основные типы HTTP-запросов включают GET, POST, PUT, DELETE, PATCH и другие. Данные в этих запросах могут передаваться через URL, заголовки или тело запроса в зависимости от типа запроса и его назначения.
Запрос для получения данных с сервера. Данные передаются в URL в виде параметров запроса.
GET /api/products?category=electronics&page=2 HTTP/1.1
Host: example.com
Запрос для отправки данных на сервер для создания ресурса. Данные передаются в теле запроса.
POST /api/products HTTP/1.1
Host: example.com
Content-Type: application/json
{
"name": "New Product",
"price": 19.99
}
Запрос для отправки данных на сервер для обновления существующего ресурса. Данные передаются в теле запроса.
PUT /api/products/1 HTTP/1.1
Host: example.com
Content-Type: application/json
{
"name": "Updated Product",
"price": 29.99
}
Запрос для удаления ресурса на сервере. Данные могут передаваться в URL или заголовках, но тело запроса обычно не используется.
DELETE /api/products/1 HTTP/1.1
Host: example.com
Запрос для частичного обновления ресурса на сервере. Данные передаются в теле запроса.
PATCH /api/products/1 HTTP/1.1
Host: example.com
Content-Type: application/json
{
"price": 24.99
}
Запрос, аналогичный GET, но сервер возвращает только заголовки ответа без тела. Данные передаются в URL, как и в GET-запросе.
HEAD /api/products HTTP/1.1
Host: example.com
Запрос для получения поддерживаемых сервером методов HTTP для указанного ресурса. Данные передаются в URL.
OPTIONS /api/products HTTP/1.1
Host: example.com
GET-запрос с использованием fetch API в JavaScript
fetch('https://example.com/api/products?category=electronics&page=2')
.then(response => response.json())
.then(data => console.log(data))
.catch(error => console.error('Error:', error));POST-запрос с использованием fetch API в JavaScript
fetch('https://example.com/api/products', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({
name: 'New Product',
price: 19.99
})
})
.then(response => response.json())
.then(data => console.log(data))
.catch(error => console.error('Error:', error));Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍2
1. Поддерживает Windows, macOS и Linux.
2. Легковесный, с открытым исходным кодом, предназначен для высокой производительности.
3. Подходит для разработки веб-приложений, облачных сервисов и микросервисов.
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍10
Это небольшие фрагменты данных, которые веб-сайты сохраняют на устройствах пользователей для хранения информации о сессии и отслеживания состояния. Куки используются для различных целей, таких как аутентификация пользователей, хранение настроек и предпочтений, а также отслеживание активности пользователей на сайте.
Уникальный идентификатор для каждого куки.
Данные, которые хранит куки.
Домен, для которого куки действителен.
Путь на сервере, для которого куки действителен.
Дата или время, когда куки должен быть удален.
Указывает, что куки должны передаваться только через HTTPS.
Указывает, что куки недоступен через JavaScript, только через HTTP(S) запросы.
Сервер отправляет куки в ответе на запрос клиента с использованием заголовка
Set-Cookie. HTTP/1.1 200 OK
Set-Cookie: sessionId=abc123; Path=/; Expires=Wed, 09 Jun 2023 10:18:14 GMT
Content-Type: text/html
Браузер автоматически добавляет соответствующие куки в заголовок
Cookie при каждом последующем запросе к серверу, для которого эти куки действительны. GET /dashboard HTTP/1.1
Host: example.com
Cookie: sessionId=abc123
Установка куки на сервере (пример на Node.js с использованием Express)
const express = require('express');
const app = express();
app.get('/', (req, res) => {
// Устанавливаем куки
res.cookie('sessionId', 'abc123', {
maxAge: 900000,
httpOnly: true
});
res.send('Куки установлены');
});
app.listen(3000, () => {
console.log('Server is running on port 3000');
});Доступ к куки на клиенте (пример на JavaScript)
// Установка куки
document.cookie = "username=JohnDoe; expires=Thu, 18 Dec 2023 12:00:00 UTC; path=/";
// Получение всех куки
let cookies = document.cookie;
console.log(cookies);
Куки с флагом
Secure передаются только по HTTPS-соединениям. Куки с флагом HttpOnly недоступны через JavaScript, что помогает защитить их от XSS-атак.Обычно один куки не должен превышать 4KB, и на одном домене может быть установлено не более 20-30 куки.
Куки могут содержать чувствительные данные, поэтому важно защищать их и использовать шифрование, если необходимо.
Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍3❤1