Визуализация данных в Kepler.gl в браузере опирается на загрузку внешних ресурсов: таблиц, GeoJSON, тайлов, изображений и векторных слоёв. Почти все эти сценарии упираются в политику браузера CORS (Cross-Origin Resource Sharing), которая определяет, может ли веб-страница обращаться к ресурсам с другого домена.
Kepler.gl сам по себе не реализует обход CORS — он наследует ограничения браузера и использует стандартный стек загрузки данных (fetch, XHR, loaders.gl). Поэтому корректная работа с внешними источниками данных напрямую зависит от конфигурации серверов и способа интеграции данных.
Kepler.gl использует связку:
Именно loaders.gl выполняет сетевые запросы к:
Каждый запрос из браузера проходит через fetch() или
XHR, а значит подчиняется CORS-ограничениям.
Типовая цепочка:
Типичная ошибка:
Access to fetch at 'https://api.example.com/data.csv' from origin 'http://localhost:3000'
has been blocked by CORS policy
Причина — сервер не возвращает:
Access-Control-Allow-Origin: *
или конкретный origin приложения.
Kepler.gl активно использует Mapbox Style Specification. При загрузке:
возникают дополнительные CORS-запросы к CDN Mapbox или кастомным тайловым серверам.
Особенно часто блокируются:
*.tiles.mapbox.comПри попытке загрузки локального JSON/CSV напрямую:
nullKepler.gl решает это через загрузку файлов в память (drag & drop), но URL-подгрузка всё равно требует HTTP(S).
Хотя Kepler.gl не управляет CORS напрямую, ряд параметров влияет на поведение загрузки данных:
dataUrlИспользуется для передачи удалённого источника:
addDataToMap({
datasets: {
info: { label: 'remote data' },
data: null,
url: 'https://example.com/data.geojson'
}
});
Если URL cross-origin, ответственность за CORS лежит на сервере.
loaders конфигурацияKepler.gl позволяет прокидывать кастомные loaders:
import { load } from '@loaders.gl/core';
load(url, CSVLoader, {
fetch: {
mode: 'cors'
}
});
Параметр mode: 'cors' не решает проблему сам по себе, но
определяет режим запроса.
При использовании кастомного style JSON:
mapStyle: {
styleType: 'custom',
style: 'https://myserver.com/style.json'
}
Все ресурсы внутри style.json также должны поддерживать CORS:
Базовая настройка:
import cors from 'cors';
import express from 'express';
const app = express();
app.use(cors({
origin: '*'
}));
Для более строгой политики:
app.use(cors({
origin: 'https://my-kepler-app.com'
}));
location /data/ {
add_header Access-Control-Allow-Origin *;
add_header Access-Control-Allow-Methods "GET, OPTIONS";
}
Для preflight-запросов:
if ($request_method = OPTIONS ) {
add_header Access-Control-Allow-Origin *;
add_header Access-Control-Allow-Methods "GET, OPTIONS";
return 204;
}
Для AWS S3 необходимо CORS-конфигурация бакета:
[
{
"AllowedOrigins": ["*"],
"AllowedMethods": ["GET"],
"AllowedHeaders": ["*"]
}
]
Без этого Kepler.gl не сможет загружать GeoJSON/CSV напрямую из bucket URL.
Когда сервер данных невозможно изменить, используется проксирование.
app.get('/proxy', async (req, res) => {
const url = req.query.url;
const response = await fetch(url);
const data = await response.text();
res.setHeader('Access-Control-Allow-Origin', '*');
res.send(data);
});
Kepler.gl получает уже “локальный” URL:
/proxy?url=https://external-site.com/data.csv
location /proxy/ {
proxy_pass https://external-site.com/;
}
Mapbox является частым источником CORS-конфликтов:
Обязательные условия:
access_tokenНекорректная конфигурация приводит к:
loaders.gl использует расширенный fetch-слой:
RequestInitcredentialsResponseПример:
load(url, GeoJSONLoader, {
fetch: {
credentials: 'omit'
}
});
Значение credentials:
omit — без cookies (рекомендуется)include — с cookies (часто ломает CORS)same-origin — только для того же доменаНельзя использовать одновременно:
Access-Control-Allow-Origin: *
Access-Control-Allow-Credentials: true
Если URL редиректится (301/302), конечный сервер тоже должен отдавать CORS-заголовки.
Некоторые CDN блокируют OPTIONS-запросы, что ломает POST/complex requests.
Проверяются:
Типичные сообщения:
Можно перехватывать загрузку:
import { setLoaderOptions } from '@loaders.gl/core';
setLoaderOptions({
fetch: (url, options) => {
console.log('loading:', url);
return fetch(url, options);
}
});
CORS не является механизмом защиты данных, а лишь ограничением браузера.
Важно учитывать:
* допустим только для публичных данныхДля стабильной работы Kepler.gl в продакшене обычно используется:
Такая архитектура минимизирует зависимость фронтенда от внешних политик доступа и снижает вероятность блокировок загрузки данных.