В веб-картографии и 3D-геовизуализации библиотека CesiumJS активно взаимодействует с внешними источниками данных: тайлы, изображения, 3D Tiles, terrain, модели glTF, GeoJSON и потоковые сервисы. Почти все эти ресурсы загружаются через HTTP(S) и подчиняются политике безопасности браузера Same-Origin Policy.
Cross-Origin Resource Sharing (CORS) определяет, может ли браузер разрешить JavaScript-коду получать доступ к ресурсам с другого домена. При отсутствии корректных CORS-заголовков загрузка данных в CesiumJS приводит к блокировкам, даже если URL корректен и сервер отвечает.
Браузер разделяет происхождение запроса по трём компонентам:
Запрос считается cross-origin, если хотя бы один компонент отличается.
При загрузке ресурсов в CesiumJS типичный поток выглядит так:
Если сервер не возвращает заголовок:
Access-Control-Allow-Origin: *
или соответствующий origin, браузер блокирует ответ, даже если сетевой запрос успешен.
В консоли браузера возникают сообщения:
No 'Access-Control-Allow-Origin' header is presentCORS policy blocked the requestResponse to preflight request doesn't pass access control checkВ CesiumJS это часто проявляется как:
Cesium.js при декодировании ресурсовНаиболее распространённая конфигурация:
location / {
add_header Access-Control-Allow-Origin *;
add_header Access-Control-Allow-Methods "GET, OPTIONS";
add_header Access-Control-Allow-Headers "Origin, Authorization, Accept";
}
Для более строгой политики:
add_header Access-Control-Allow-Origin "https://example.com";
Важно учитывать preflight-запросы OPTIONS:
if ($request_method = OPTIONS) {
add_header Access-Control-Allow-Origin *;
add_header Access-Control-Allow-Methods "GET, POST, OPTIONS";
add_header Access-Control-Allow-Headers "Content-Type, Authorization";
return 204;
}
В .htaccess или конфигурации виртуального хоста:
Header set Access-Control-Allow-Origin "*"
Header set Access-Control-Allow-Methods "GET, OPTIONS"
Header set Access-Control-Allow-Headers "Origin, Content-Type, Accept"
Для API и статических ресурсов:
import express from "express";
import cors from "cors";
const app = express();
app.use(cors({
origin: "*",
methods: ["GET", "POST", "OPTIONS"],
allowedHeaders: ["Content-Type", "Authorization"]
}));
При использовании облачного сервиса данных Cesium ion доступ к ассетам происходит через signed URLs.
Особенности:
Инициализация:
import { Ion } from "cesium";
Ion.defaultAccessToken = "YOUR_TOKEN";
Проблемы CORS в этом случае обычно связаны не с сервером ion, а с промежуточными прокси или корпоративными фильтрами.
При запуске CesiumJS локально часто возникает конфликт из-за
file:// протокола.
Запрещённые сценарии:
Корректные варианты:
python -m http.server 8080
npx serve .
export default {
server: {
cors: true
}
}
3D Tiles используют множественные уровни запросов:
Каждый из этих запросов требует CORS.
Особенно критично:
Preflight возникает при:
CesiumJS может инициировать preflight при использовании:
Request объектовПример:
viewer.imageryLayers.addImageryProvider(
new Cesium.UrlTemplateImageryProvider({
url: "https://tiles.example.com/{z}/{x}/{y}.png",
headers: {
Authorization: "Bearer token"
}
})
);
Такой запрос почти всегда вызывает OPTIONS preflight.
Когда сервер не поддерживает CORS, используется проксирование.
import express from "express";
import fetch from "node-fetch";
const app = express();
app.get("/proxy", async (req, res) => {
const url = req.query.url;
const response = await fetch(url);
const data = await response.arrayBuffer();
res.set("Access-Control-Allow-Origin", "*");
res.send(Buffer.from(data));
});
CesiumJS:
url: "http://localhost:3000/proxy?url=https://example.com/tiles/{z}/{x}/{y}.png"
При использовании AWS S3 необходимо явно включить CORS-конфигурацию бакета:
[
{
"AllowedOrigins": ["*"],
"AllowedMethods": ["GET"],
"AllowedHeaders": ["*"],
"ExposeHeaders": []
}
]
Без этого CesiumJS не сможет загрузить:
GitHub Pages по умолчанию поддерживает CORS для статических файлов, но проблемы возникают при:
Особенность:
Основные методы диагностики:
Проверка:
viewer.scene.globe.tileLoadProgressEvent.addEventListener(function (queueLength) {
console.log(queueLength);
});
Cesium.Cesium3DTileset.debugShowBoundingVolume = true;
* вместе с credentials* при авторизацииНеправильная конфигурация CORS не только блокирует загрузку, но и влияет на:
При корректной настройке:
При создании собственного ImageryProvider или
TerrainProvider:
fetch или XHRПример:
class CustomProvider extends Cesium.ImageryProvider {
requestImage(x, y, level) {
return Cesium.Resource.fetchImage({
url: this.urlTemplate
.replace("{x}", x)
.replace("{y}", y)
.replace("{z}", level)
});
}
}