feat: enable CORS headers in the HTTP API (#2594)

Closes #2558.

Enables the Arduino WebServer's built-in CORS support
(`enableCORS(true)`), which adds
`Access-Control-Allow-Origin/Methods/Headers: *` to every response, and
answers preflight `OPTIONS` requests with `204` in `handleNotFound()` —
routes are registered per-method, so OPTIONS always lands there. The
AP-mode captive-portal redirect is untouched (the OPTIONS check runs
before it, and browsers don't send preflights for captive-portal
probes).

This lets web-based clients and PWAs served from other origins call the
JSON API (`/api/status`, `/api/files`, `/api/settings`, ...) directly
from the browser.

Overhead is three static response headers; no behavior change for the
built-in web UI.

Note: not yet tested on hardware.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-authored-by: metoli <metoli@metoli-Mac-mini.local>
Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
metoli86
2026-07-15 18:35:10 -04:00
committed by GitHub
co-authored by metoli Claude Fable 5
parent 63093e606c
commit a2db43d235
+12
View File
@@ -132,6 +132,11 @@ void CrossPointWebServer::begin() {
return;
}
// Add Access-Control-Allow-* headers to every response so web-based clients
// and PWAs on other origins can use the HTTP API. Preflight OPTIONS requests
// are answered in handleNotFound().
server->enableCORS(true);
// Setup routes
LOG_DBG("WEB", "Setting up routes...");
server->on("/", HTTP_GET, [this] { handleRoot(); });
@@ -353,6 +358,13 @@ void CrossPointWebServer::handleJszip() const {
}
void CrossPointWebServer::handleNotFound() const {
// CORS preflight: routes are registered per-method, so OPTIONS requests land
// here. The Access-Control-Allow-* headers are added by enableCORS().
if (server->method() == HTTP_OPTIONS) {
server->send(204, "text/plain", "");
return;
}
// in AP mode, redirect unmatched browser/captive-portal requests to "/" so the OS auto-opens the browser
// API requests (/api/*) still return 404 so XHR errors surface correctly
// see https://en.wikipedia.org/wiki/Captive_portal#Detection