hoeken/PsychicHttp

CORS error

Closed this issue · 2 comments

Hi! I'm wondering how to bypass CORS errors.

I have added these default headers to my server:

DefaultHeaders::Instance().addHeader("Access-Control-Allow-Origin", "*");
DefaultHeaders::Instance().addHeader("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS");
DefaultHeaders::Instance().addHeader("Access-Control-Allow-Headers", "Content-Type, Authorization, Accept");

I have also setup my notfound handler like this so it will return a 200 OK response if the method is HTTP_OPTIONS

server.onNotFound(std::bind(&HsHServer::notFoundHandler,this,std::placeholders::_1));

esp_err_t HsHServer::notFoundHandler(PsychicRequest *request){
    Serial.printf(
        "\n[Server] - 404\nURL: %s\nMethod: %s\nBody: %s\n",
        request->url().c_str(),
        request->methodStr().c_str(),
        request->body().c_str()
    );
    if( request->method() == HTTP_OPTIONS ){
        return request->reply(200);
    }
    return request->reply(404);
}

But I still get CORS error in the browser. Any more ideas? I have also tried to create a new response object, set these headers and send that response instead of replying to the request. Did not work.

What I have found is that the notFoundHandler does not capture OPTIONS requests.
When I added two handlers for the same endpoint, one for HTTP_GET and one for HTTP_OPTIONS it started to work without additional tinkering.

Right now it looks like this:

DefaultHeaders::Instance().addHeader("Access-Control-Allow-Origin", "*");
DefaultHeaders::Instance().addHeader("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS");
DefaultHeaders::Instance().addHeader("Access-Control-Allow-Headers", "Content-Type, Authorization, Accept");

// Return 200 for OPTIONS type
server.on("/getSysInfo", HTTP_OPTIONS, [](PsychicRequest *request) {
    return request->reply(200);
});
// Handle the actual request
server.on("/getSysInfo",HTTP_GET,[](PsychicRequest *request){
});

This is a really bad design since I must make a copy of every handler in my app.
Instead it would be good to capture every HTTP_OPTIONS request and handle them before.
Some middleware to the server since the notFoundHandler does not capture everything it seems.

@hoeken Is this possible somehow?

This also doesn't seem to work
Okay this works. I removed the OPTIONS endpoints, added this before the notFoundHandler and the CROS works with the default headers

server.on("/*", HTTP_OPTIONS, [](PsychicRequest *request) {
    printf(
        "\n[Server] - OPTIONS\nURL: %s\nMethod: %s\nBody: %s\n",
        request->url().c_str(),
        request->methodStr().c_str(),
        request->body().c_str()
    );
    return request->reply(200);
});