В браузерной среде любые запросы к внешним источникам данных подчиняются политике одинакового источника (Same-Origin Policy). При работе с веб-картами это становится критическим фактором, поскольку карты почти всегда состоят из множества внешних ресурсов: тайловых серверов, векторных API, WMS/WFS сервисов, шрифтов, изображений и данных пространственных слоёв.
CORS (Cross-Origin Resource Sharing) представляет собой стандарт, позволяющий серверу явно разрешать доступ к своим ресурсам с других доменов. В картографических приложениях это напрямую определяет, можно ли отобразить внешний слой без прокси, ошибок загрузки или блокировки браузером.
OpenLayers активно использует браузерные механизмы загрузки ресурсов
через XMLHttpRequest, fetch и
<img> элементы. В зависимости от типа слоя
применяются разные стратегии:
ol/source/XYZ,
ol/source/TileWMS)ol/source/ImageWMS)ol/source/Vector,
ol/format/GeoJSON, ol/format/WFS)ol/source/VectorTile)Каждый из этих типов по-разному взаимодействует с CORS, и ошибка на уровне заголовков сервера может привести либо к частичному отображению данных, либо к полной недоступности слоя.
Тайловые слои являются наиболее чувствительными к настройкам
кросс-доменных запросов. При использовании ol/source/XYZ
или аналогичных источников браузер загружает изображения через
<img>.
Если сервер не возвращает заголовок:
Access-Control-Allow-Origin: *
или конкретный домен, возникают ограничения:
getImageData)При корректной настройке:
Ключевая настройка OpenLayers:
new ol.source.XYZ({
url: 'https://tile.server/{z}/{x}/{y}.png',
crossOrigin: 'anonymous'
})
Параметр crossOrigin критически важен: он заставляет
браузер выполнять запрос как CORS-запрос, а не как «непрозрачную»
загрузку изображения.
WMS-сервисы часто используются для динамических картографических
изображений. В OpenLayers они реализуются через
ol/source/ImageWMS.
Особенность заключается в том, что каждый запрос формирует изображение на сервере, а не получает готовый тайл.
new ol.source.ImageWMS({
url: 'https://gis.server/wms',
params: { LAYERS: 'roads' },
crossOrigin: 'anonymous'
})
Если сервер не поддерживает CORS:
В некоторых GIS-серверах (GeoServer, MapServer) требуется явная настройка CORS-фильтра.
Векторные источники используют fetch или
XMLHttpRequest, поэтому CORS становится обязательным
условием.
Пример GeoJSON:
new ol.source.Vector({
url: 'https://api.server/data.geojson',
format: new ol.format.GeoJSON(),
crossOrigin: 'anonymous'
})
Если сервер не возвращает корректные заголовки:
Для корректной работы:
Access-Control-Allow-Origin: *
Access-Control-Allow-Methods: GET
Access-Control-Allow-Headers: Content-Type
WFS (Web Feature Service) чаще использует POST-запросы, что усложняет CORS-конфигурацию.
При работе с фильтрами (OGC Filter Encoding):
Access-Control-Allow-HeadersОтсутствие поддержки preflight приводит к полной недоступности слоя, даже если GET-запросы разрешены.
Некоторые источники используют промежуточные описательные форматы:
Для них характерны дополнительные проблемы:
OpenLayers не обходит CORS-ограничения, поэтому вся цепочка запросов должна быть разрешена сервером.
Одним из наиболее критичных эффектов CORS является «загрязнение canvas».
Если хотя бы один слой загружен без CORS, запрещаются операции:
toDataURL()getImageData()Даже один некорректный тайл может сделать весь canvas недоступным для экспорта.
При отсутствии возможности изменить сервер применяется сервер-прокси.
Схема:
OpenLayers → прокси → внешний GIS сервер
Прокси добавляет нужные заголовки:
Access-Control-Allow-Origin: *
и преобразует запросы.
Пример логики прокси:
Это особенно актуально для:
При использовании CDN часто возникает распределённая архитектура:
Для корректной работы требуется единая политика CORS между всеми доменами.
Типичные ошибки:
Использование:
Access-Control-Allow-Origin: *
имеет ограничения:
Альтернатива:
Access-Control-Allow-Origin: https://app.domain.com
В GIS-системах часто используется whitelist доменов.
Практически все источники OpenLayers поддерживают параметр:
crossOrigin: 'anonymous'
Возможные значения:
anonymous — стандартный CORS-запрос без cookiesuse-credentials — с передачей учётных данныхnull — отключение CORS-режимаНеправильный выбор значения приводит к:
Preflight-запросы не обрабатываются сервером.
HTTPS-карта обращается к HTTP-сервису.
Заголовки есть на API, но отсутствуют на изображениях.
CORS-заголовки теряются при 302/301 редиректах.
Даже при корректном сервере canvas становится недоступным.
Основные признаки:
Методы анализа:
VectorTile источники используют бинарные форматы (PBF), которые особенно чувствительны к CORS.
new ol.source.VectorTile({
url: 'https://tiles.server/{z}/{x}/{y}.pbf',
format: new ol.format.MVT(),
crossOrigin: 'anonymous'
})
Без CORS:
Некорректная настройка может приводить к:
Правильная CORS-конфигурация позволяет: