diff --git a/src/network/CrossPointWebServer.cpp b/src/network/CrossPointWebServer.cpp index 5624b76a..a6b2e103 100644 --- a/src/network/CrossPointWebServer.cpp +++ b/src/network/CrossPointWebServer.cpp @@ -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