CORS (Cross-Origin Resource Sharing) — это механизм,
позволяющий браузеру контролировать доступ веб-приложений к ресурсам,
расположенным на других доменах. В контексте Stencil важно понимать, что
сам фреймворк не управляет CORS напрямую: все запросы к сторонним API
выполняются через стандартные браузерные механизмы (fetch,
XMLHttpRequest). Настройка CORS требует правильной
конфигурации сервера, к которому осуществляется запрос.
При попытке обратиться к ресурсам с другого домена без корректных заголовков сервер возвращает ошибку вида:
Access to fetch at 'https://example.com/api/data' from origin 'http://localhost:3333' has been blocked by CORS policy
Основные причины:
Access-Control-Allow-Origin на
сервере.Authorization,
Content-Type: application/json) или методы
(PUT, DELETE), что требует
preflight-запроса (OPTIONS).Для корректной работы Stencil-компонентов с внешними API необходимо:
Access-Control-Allow-Origin: http://localhost:3333
Или использовать универсальный доступ (не рекомендуется для production):
Access-Control-Allow-Origin: *
Access-Control-Allow-Methods: GET, POST, PUT, DELETE, OPTIONS
Access-Control-Allow-Headers: Content-Type, Authorization
Access-Control-Allow-Credentials: true
Stencil использует Dev Server, который может
проксировать запросы к API, обходя ограничения CORS. В файле
stencil.config.ts можно настроить прокси:
import { Config } from '@stencil/core';
export const config: Config = {
devServer: {
proxy: {
'/api': {
target: 'https://example.com',
changeOrigin: true,
secure: false,
},
},
},
};
Пояснения:
/api — путь, на который будут перенаправляться
запросы.target — адрес внешнего API.changeOrigin: true — заменяет заголовок
Origin на адрес целевого сервера.secure: false — отключает проверку SSL-сертификата для
локальной разработки.Таким образом, все запросы к /api/... внутри
Stencil-приложения будут автоматически проксироваться, и браузер не
заблокирует их из-за CORS.
При запросах, где требуется авторизация через cookie или токен,
необходимо учитывать параметры fetch:
fetch('https://example.com/api/data', {
method: 'GET',
credentials: 'include', // отправка cookie
headers: {
'Content-Type': 'application/json',
'Authorization': 'Bearer TOKEN'
}
})
Ключевые моменты:
credentials: 'include' позволяет отправлять cookie
вместе с запросом.Access-Control-Allow-Credentials: true и не использовать
* в Access-Control-Allow-Origin.Когда отправляется запрос с методами, отличными от GET/POST, или с
нестандартными заголовками, браузер выполняет
preflight-запрос типа OPTIONS. Сервер
должен корректно его обрабатывать:
OPTIONS /api/data HTTP/1.1
Origin: http://localhost:3333
Access-Control-Request-Method: PUT
Access-Control-Request-Headers: Content-Type
Ответ сервера:
HTTP/1.1 204 No Content
Access-Control-Allow-Origin: http://localhost:3333
Access-Control-Allow-Methods: GET, POST, PUT, DELETE
Access-Control-Allow-Headers: Content-Type
Если сервер игнорирует preflight-запрос, основной запрос будет заблокирован браузером.
* в
Access-Control-Allow-Origin.Предположим, Stencil-компонент должен получать список пользователей с внешнего API:
@Component({
tag: 'user-list',
styleUrl: 'user-list.css',
shadow: true
})
export class UserList {
@State() users: any[] = [];
async componentWillLoad() {
try {
const res = await fetch('/api/users', { credentials: 'include' });
this.users = await res.json();
} catch (e) {
console.error('Ошибка запроса:', e);
}
}
render() {
return (
<ul>
{this.users.map(user => (
<li>{user.name}</li>
))}
</ul>
);
}
}
Здесь '/api/users' проксируется через Dev Server к
реальному серверу, а все настройки CORS обрабатываются на сервере.
Хотя Stencil не имеет встроенных инструментов для управления CORS,
правильное сочетание серверных заголовков, проксирования и параметров
fetch позволяет строить безопасные и стабильные
кросс-доменные приложения.