0

With an nodeMCUv2 I want:

  • to start a wifi server with ESP8266WebServer.h
  • serve a root html page which will interact with the ESP and fetch external data

Issue: CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.'

Tried to make CORS happy, by either one of the followings, but didn't help:

.sendHeader("Access-Control-Allow-Origin", "*");

.enableCORS(true);

#include <ESP8266WebServer.h>
ESP8266WebServer srvAmb(80);
void handleRoot(){
// srvAmb.sendHeader("Access-Control-Allow-Origin", "*");
   srvAmb.enableCORS(true);
   srvAmb.send(200,"text/html; charset=utf-8", myRootWebPagWithJSExternalFetch);
}
void setup(){
...
    srvAmb.on("/", handleRoot);
...

Part of the served root html page:

try{
  const Qresponse = await fetch( "https://zenquotes.io/api/random" );
  const Qdata = await Qresponse.json();
  console.log(Qdata);
  ...
} catch (error) {
  console.error(error);
}

Console log in Chromium:

Access to fetch at 'https://zenquotes.io/api/random' from origin '192....' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource. If an opaque response serves your needs, set the request's mode to 'no-cors' to fetch the resource with CORS disabled.

So, how does one fetch external data from the browser running on PC, smartphone, etc?

Thanks

P.S. One could ask the server to fetch the data, prior to supplying the html page, but that's not esp server's job.

P.P.S. I hadn't the credit to create tag keywords such as: fetch, CORS, Allow-Origin, policy

REM: under How to allow cross-domain requests on ESP8266WebServer

it is suggested that .sendHeader("Access-Control-Allow-Origin", "*") could be deprecated, very well but ArduinoIDE does not raise any warning; anyway suggested solution fails.

Looking at the source code https://github.com/esp8266/ESPWebServer/blob/master/src/ESP8266WebServer.cpp, the method sendHeader() on line 238, has a 3rd parameter(a boolean) that if set to true, puts before the passed name & value before the already passed header, otherwise puts it after, aka the declarative order is important.

Viz, what's the valid header the esp server needs to send?? Especially, has Chromium details, states:

Request URL: zenquotes.io/api/random

Request Method: GET

Status Code: 200

Referrer Policy: strict-origin-when-cross-origin

See also: https://javascript.info/fetch-crossorigin

3
  • One thing, because I struggled with CORS in a different context lately: Are you sure, that your browsers cache doesn't interfere here? I had the issue that setting allow origin to * wouldn't help, but as soon as I used a different browser (or in my case a fresh profile of firefox), it was working.
    – chrisl
    Commented Nov 25, 2022 at 10:29
  • @chrisl. NO. But I wonder if it has nothething to do with the fact that the fetch is https while the connection with ESP is http. GET zenquotes.io/api/random net::ERR_FAILED 200 stackoverflow.com/questions/22665232/… Commented Nov 25, 2022 at 11:17
  • Details in Chromium: states that the header is missing: A cross-origin resource sharing (CORS) request was blocked because of invalid or missing response headers of the request or the associated preflight request . ... Request Status Preflight Request (if problematic) Header Problem Invalid Value (if available) random blocked Access-Control-Allow-Origin Missing Header So it does not do job as Chromium 107 expects. web.dev/cross-origin-resource-sharing/?utm_source=devtools and developer.mozilla.org/en-US/docs/Web/HTTP/CORS Commented Nov 25, 2022 at 11:35

1 Answer 1

1

The issue is URL specific.

Indeed, if I change API, namely

const Qresponse = await fetch( "https://zenquotes.io/api/random" );

by for example:

const Qresponse = await fetch( "https://api.open-meteo.com/v1/meteofrance?latitude=49.71&longitude=4.16&daily=sunset&timezone=Europe%2FBerlin" );

then it works.

I presume that I comes from network developper tools info in Chromium:

Referrer Policy: strict-origin-when-cross-origin

claiming a strict origin for zenquotes.io's API. My esp server code being:

void handleRoot(){
    srvAmb.sendHeader("Access-Control-Allow-Origin", "*", 1);
    srvAmb.send(200,"text/html; charset=utf-8", myRootWebPagWithJSExternalFetch);
}

Remark, with or without the additional 3rd param of sendHeader() it works.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.