Будет ли работать CORS при отправке формы?
Комментарии (1)
Ответ сгенерирован нейросетью и может содержать ошибки
CORS при отправке формы
CORS (Cross-Origin Resource Sharing) - это механизм безопасности браузера, который контролирует доступ к ресурсам с разных доменов. Однако, CORS работает не одинаково для разных типов запросов. Отправка HTML форм (form submission) имеет особые правила в отношении CORS.
Ответ: Нет, CORS не будет применяться при обычной отправке формы
Обычная HTML форма отправляется без CORS проверок, если форма отправляется с помощью элемента <form> и не использует JavaScript для модификации запроса. Это исторические причины безопасности.
Различия: Form vs AJAX/Fetch
1. Обычная форма (NO CORS)
<!-- Эта форма отправится без CORS проверок -->
<form action="https://api.example.com/submit" method="POST">
<input type="text" name="username" value="John" />
<input type="password" name="password" value="secret" />
<button type="submit">Submit</button>
</form>
<!-- Результат: форма отправится, даже если CORS запрещён -->
<!-- Но браузер перенаправит пользователя на другой домен -->
Как это работает:
HTML форма (POST)
https://example.com/page -> https://api.example.com/submit
|
| (НЕ проверяется CORS)
v
Форма отправляется
|
v
Результат приходит в текущий документ
2. AJAX/Fetch запрос (WITH CORS)
// Этот запрос ТРЕБУЕТ CORS
fetch('https://api.example.com/submit', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({ username: 'John', password: 'secret' })
})
.then(response => response.json())
.catch(error => console.error('CORS error:', error));
// Результат: CORS error - запрос будет заблокирован без правильных headers
Когда CORS применяется при отправке формы?
CORS проверяется только когда форма имеет определённые свойства:
1. Нестандартные Content-Type заголовки
<!-- ✅ Простая форма - БЕЗ CORS -->
<form action="https://api.example.com/submit" method="POST">
<!-- enctype по умолчанию: application/x-www-form-urlencoded -->
<input type="text" name="data" />
<button type="submit">Submit</button>
</form>
<!-- ✅ Форма с файлами - БЕЗ CORS -->
<form action="https://api.example.com/submit" method="POST" enctype="multipart/form-data">
<input type="file" name="file" />
<button type="submit">Submit</button>
</form>
<!-- ❌ Форма с JSON - С CORS -->
<form action="https://api.example.com/submit" method="POST" enctype="application/json">
<!-- Это вызовёт CORS preflight запрос -->
<input type="text" name="data" />
<button type="submit">Submit</button>
</form>
2. Нестандартные заголовки
<!-- Если добавить custom headers через JavaScript - CORS включается -->
<script>
const form = document.querySelector('form');
form.addEventListener('submit', (e) => {
e.preventDefault();
const formData = new FormData(form);
fetch('https://api.example.com/submit', {
method: 'POST',
headers: {
'X-Custom-Header': 'value' // Нестандартный заголовок
},
body: formData
});
// Теперь CORS ТРЕБУЕТСЯ!
});
</script>
Простые запросы (Simple Requests) - без CORS
Simple Request - это запрос, который НЕ требует CORS preflight:
Условия:
1. Метод: GET, HEAD, POST
2. Content-Type: application/x-www-form-urlencoded, multipart/form-data, text/plain
3. Нет кастомных заголовков (кроме стандартных)
<!-- Простой POST запрос - БЕЗ CORS preflight -->
<form action="https://api.example.com/submit" method="POST">
<input type="text" name="username" />
<button type="submit">Submit</button>
</form>
<!-- Что отправляется -->
POST /submit HTTP/1.1
Host: api.example.com
Content-Type: application/x-www-form-urlencoded
username=John
<!-- CORS headers НЕ проверяются! -->
Сложные запросы (Preflight Requests) - с CORS
Preflight Request - это автоматический OPTIONS запрос перед основным запросом:
// Это вызовет CORS preflight
fetch('https://api.example.com/submit', {
method: 'POST',
headers: {
'Content-Type': 'application/json' // Нестандартный для форм
},
body: JSON.stringify({ username: 'John' })
});
// Браузер отправит:
// OPTIONS /submit HTTP/1.1
// Origin: https://example.com
// Access-Control-Request-Method: POST
// Access-Control-Request-Headers: content-type
// Сервер должен ответить:
// Access-Control-Allow-Origin: https://example.com
// Access-Control-Allow-Methods: POST
// Access-Control-Allow-Headers: content-type
Практические примеры
Пример 1: Обычная форма (работает везде)
<!DOCTYPE html>
<html>
<head>
<title>Form Submission</title>
</head>
<body>
<!-- Эта форма отправится даже на другой домен без CORS -->
<form action="https://api.example.com/subscribe" method="POST">
<input type="email" name="email" placeholder="Email" required />
<button type="submit">Subscribe</button>
</form>
<!-- Результат: страница перейдёт на https://api.example.com/subscribe -->
</body>
</html>
Пример 2: AJAX форма (требует CORS)
<!DOCTYPE html>
<html>
<body>
<form id="myForm">
<input type="email" name="email" placeholder="Email" required />
<button type="submit">Subscribe</button>
</form>
<script>
document.getElementById('myForm').addEventListener('submit', (e) => {
e.preventDefault();
const formData = new FormData(e.target);
// Это требует CORS!
fetch('https://api.example.com/subscribe', {
method: 'POST',
body: formData // application/x-www-form-urlencoded
})
.then(res => res.json())
.catch(err => console.error('CORS error:', err));
// Без правильных CORS headers на сервере - будет ошибка
});
</script>
</body>
</html>
Пример 3: JSON отправка (требует CORS)
<script>
document.getElementById('myForm').addEventListener('submit', (e) => {
e.preventDefault();
const data = {
email: e.target.email.value
};
// JSON Content-Type требует CORS preflight
fetch('https://api.example.com/subscribe', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify(data)
})
.catch(err => console.error('CORS error:', err));
});
</script>
Как сервер должен обработать CORS
// Node.js / Express
const express = require('express');
const app = express();
// Middleware для CORS
app.use((req, res, next) => {
res.header('Access-Control-Allow-Origin', '*'); // или конкретный домен
res.header('Access-Control-Allow-Methods', 'GET, POST, OPTIONS');
res.header('Access-Control-Allow-Headers', 'Content-Type');
if (req.method === 'OPTIONS') {
return res.send(200);
}
next();
});
// Обработка POST запроса
app.post('/subscribe', (req, res) => {
res.json({ success: true });
});
Важные моменты
1. Обычная форма НЕ будет показывать CORS ошибку
<!-- Даже если CORS запрещён, форма отправится -->
<form action="https://blocked-domain.com/submit" method="POST">
<input type="text" name="data" />
<button type="submit">Submit</button>
</form>
<!-- Что произойдёт:
1. Форма отправляется
2. Браузер перенаправляет пользователя на blocked-domain.com
3. CORS ошибка НЕ появляется в консоли
4. Обработать ответ JavaScript не сможет
-->
2. Fetch ВСЕГДА требует CORS
// Fetch ВСЕГДА проверяет CORS (в отличие от форм)
fetch('https://blocked-domain.com/api')
.catch(err => console.error('CORS error')); // CORS ошибка в консоли
3. Workaround: отправить форму, скрытый iframe
<!-- Исторический способ обхода CORS (deprecated) -->
<form action="https://api.example.com/submit" method="POST" target="hidden-frame">
<input type="text" name="data" />
<button type="submit">Submit</button>
</form>
<iframe name="hidden-frame" style="display:none;"></iframe>
<!-- Форма отправляется в скрытый iframe, CORS не проверяется -->
Сравнительная таблица
╔═══════════════════════════════════════════════════════════════╗
║ Тип запроса │ CORS проверяется │ Может быть заблокирован ║
╠═══════════════════════════════════════════════════════════════╣
║ HTML форма │ НЕТ │ НЕТ (но результат не ║
║ (simple request) │ │ доступен JavaScript) ║
╠═══════════════════════════════════════════════════════════════╣
║ HTML форма │ ДА │ ДА (нестандартный ║
║ (complex request) │ │ Content-Type) ║
╠═══════════════════════════════════════════════════════════════╣
║ Fetch / XMLHttpRequest │ ДА │ ДА (требует CORS на ║
║ │ │ сервере) ║
╠═══════════════════════════════════════════════════════════════╣
║ <script src=""> │ НЕТ (JSONP) │ НЕТ (execute) ║
║ <img>, <link>, etc. │ │ ║
╚═══════════════════════════════════════════════════════════════╝
Вывод
CORS НЕ применяется при отправке обычной HTML формы (с методом POST и стандартным Content-Type). Форма отправится без CORS проверок, но браузер не даст JavaScript доступ к ответу, если это другой домен.
CORS применяется когда:
- Используется Fetch или XMLHttpRequest
- Нестандартные заголовки или Content-Type
- Сложные запросы (preflight)
Это исторически сложилось для совместимости с древним HTML, где формы всегда могли отправляться куда угодно, но JavaScript в браузере не имел доступа к результатам с других доменов.