CORS (Cross-Origin Resource Sharing) в контексте Mapbox GL JS определяет правила, по которым браузер разрешает или блокирует загрузку географических ресурсов (тайлов, шрифтов, изображений, спрайтов) с доменов, отличных от домена текущего приложения. В веб-картографии это критический механизм, поскольку практически все данные — векторные тайлы, растровые слои, стили и шрифты — часто приходят с удалённых серверов.
В Mapbox GL JS рендеринг выполняется через WebGL, а это накладывает дополнительные ограничения: любая текстура, загруженная с другого источника без корректных CORS-заголовков, может привести к блокировке отрисовки или «tainted canvas», что делает невозможным использование карты для экспорта изображений или постобработки.
Mapbox GL JS опирается на несколько типов удалённых ресурсов:
Каждый из этих типов загружается через стандартный сетевой стек браузера, а значит подчиняется CORS-политике.
Ключевой момент заключается в том, что Mapbox GL JS не обходит CORS-ограничения — он полностью зависит от корректной конфигурации HTTP-ответов сервера.
Для успешной загрузки ресурсов сервер должен возвращать заголовки:
Access-Control-Allow-Origin: *
или более строго:
Access-Control-Allow-Origin: https://example.com
Дополнительно могут требоваться:
Access-Control-Allow-Methods: GET, OPTIONS
Access-Control-Allow-Headers: Content-Type
Для ресурсов, использующих кэширование и предварительные запросы, важно корректно обрабатывать OPTIONS preflight.
Сервисы Mapbox (tiles, styles, sprites, glyphs) уже настроены на корректную работу с CORS. Это означает:
Access-Control-Allow-Origin: *Это делает интеграцию прозрачной при использовании официальных источников данных.
При подключении собственных серверов тайлов возникают типичные ограничения. Например:
В результате возникают ошибки:
No 'Access-Control-Allow-Origin' header is present on the requested resource
или
Blocked by CORS policy: Response to preflight request doesn't pass access control check
Mapbox GL JS использует WebGL для отрисовки. Это создаёт дополнительное ограничение:
map.getCanvas().toDataURL()
перестаёт работатьДаже если визуально карта отображается корректно, отсутствие CORS может проявиться только при попытке экспорта.
В Mapbox GL JS ключевым инструментом контроля сетевых запросов
является transformRequest.
Он позволяет перехватывать все запросы к ресурсам и модифицировать их:
Пример базовой конфигурации:
const map = new mapboxgl.Map({
container: 'map',
style: 'mapbox://styles/mapbox/streets-v12',
transformRequest: (url, resourceType) => {
return {
url,
headers: resourceType === 'Tile' ? { 'X-Custom-Header': 'value' } : {}
};
}
});
Для ресурсов изображений браузер использует механизм
crossOrigin. В контексте Mapbox GL JS это критично для:
Типовые значения:
anonymous — загрузка без cookiesuse-credentials — с cookies (требует строгой настройки
сервера)При неправильной настройке даже корректные CORS-заголовки могут не помочь, если режим загрузки не совпадает.
Векторные тайлы особенно чувствительны к CORS, поскольку:
Если сервер тайлов не поддерживает CORS:
Растровые тайлы загружаются как изображения (img
элементы). Для них CORS важен в контексте:
Без корректного CORS изображения становятся «opaque» и теряют доступность для GPU-операций.
Шрифты в Mapbox GL JS загружаются в формате PBF через endpoint glyphs.
Если CORS настроен неправильно:
Важно, что glyphs часто кэшируются агрессивно, и ошибки могут сохраняться даже после исправления сервера.
Спрайты состоят из:
Оба ресурса обязаны иметь одинаковую CORS-политику.
Несовпадение приводит к ситуации:
GeoJSON-источники также подчиняются CORS, если загружаются по URL:
source: {
type: 'geojson',
data: 'https://example.com/data.geojson'
}
Если сервер не возвращает CORS-заголовки:
При невозможности изменить сервер применяется проксирование:
Пример логики прокси:
Browser → same-origin proxy → tile server
Преимущества:
Недостатки:
При сложных запросах браузер выполняет preflight:
OPTIONS /tile/12/1200/1530.pbf
Если сервер не отвечает корректно:
Оптимизация включает:
Типовые сценарии проблем:
Access-Control-Allow-OriginКаждая из этих проблем может проявляться не сразу, а только при определённых масштабах или уровнях зума.
Устойчивые архитектуры обычно включают:
Типовой подход:
transformRequest: (url, resourceType) => {
if (url.startsWith('http://legacy-tiles.com')) {
return {
url: `/proxy?url=${encodeURIComponent(url)}`
};
}
return { url };
}
CORS влияет не только на доступность, но и на скорость:
Оптимальная конфигурация минимизирует cross-origin запросы в критическом пути рендеринга тайлов.