user87699: 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

user87699: 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.

87699: <p>With an nodeMCUv2 I want:</p>
<ul>
<li>to start a wifi server with ESP8266WebServer.h</li>
<li>serve a root html page which will interact with the ESP and fetch external data</li>
</ul>
<p><strong>Issue:</strong>
CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.'</p>
<p>Tried to make CORS happy, by either one of the followings, but didn't help:</p>
<p>.sendHeader(&quot;Access-Control-Allow-Origin&quot;, &quot;*&quot;);</p>
<p>.enableCORS(true);</p>
<pre><code>#include &lt;ESP8266WebServer.h&gt;
ESP8266WebServer srvAmb(80);
void handleRoot(){
// srvAmb.sendHeader(&quot;Access-Control-Allow-Origin&quot;, &quot;*&quot;);
   srvAmb.enableCORS(true);
   srvAmb.send(200,&quot;text/html; charset=utf-8&quot;, myRootWebPagWithJSExternalFetch);
}
void setup(){
...
    srvAmb.on(&quot;/&quot;, handleRoot);
...
</code></pre>
<p>Part of the served root html page:</p>
<pre><code>try{
  const Qresponse = await fetch( &quot;https://zenquotes.io/api/random&quot; );
  const Qdata = await Qresponse.json();
  console.log(Qdata);
  ...
} catch (error) {
  console.error(error);
}
</code></pre>
<p>Console log in Chromium:</p>
<blockquote>
<p>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.</p>
</blockquote>
<p>So, how does one fetch external data from the browser running on PC, smartphone, etc?</p>
<p>Thanks</p>
<p>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>P.P.S. I hadn't the credit to create tag keywords such as:
fetch, CORS, Allow-Origin, policy</p>
<p>REM: under <a href="https://arduino.stackexchange.com/questions/58457/how-to-allow-cross-domain-requests-on-esp8266webserver/91419#91419">How to allow cross-domain requests on ESP8266WebServer</a></p>
<p>it is suggested that .sendHeader(&quot;Access-Control-Allow-Origin&quot;, &quot;*&quot;) could be deprecated, very well but ArduinoIDE does not raise any warning; anyway suggested solution fails.</p>
<p>Looking at the source code <a href="https://github.com/esp8266/ESPWebServer/blob/master/src/ESP8266WebServer.cpp" rel="nofollow noreferrer">https://github.com/esp8266/ESPWebServer/blob/master/src/ESP8266WebServer.cpp</a>,
the method sendHeader() on line 238, has a 3rd parameter(a boolean) that if set to true, puts before the passed name &amp; value before the already passed header, otherwise puts it after, aka the declarative order is important.</p>
<p>Viz, what's the valid header the esp server needs to send??
Especially, has Chromium details, states:</p>
<blockquote>
<p>Request URL: zenquotes.io/api/random</p>
</blockquote>
<blockquote>
<p>Request Method: GET</p>
</blockquote>
<blockquote>
<p>Status Code: 200</p>
</blockquote>
<blockquote>
<p>Referrer Policy: strict-origin-when-cross-origin</p>
</blockquote>
<p>See also: <a href="https://javascript.info/fetch-crossorigin" rel="nofollow noreferrer">https://javascript.info/fetch-crossorigin</a></p>
 87699: <p>The issue is URL specific.</p>
<p>Indeed, if I change API, namely</p>
<pre><code>const Qresponse = await fetch( &quot;https://zenquotes.io/api/random&quot; );
</code></pre>
<p>by for example:</p>
<pre><code>const Qresponse = await fetch( &quot;https://api.open-meteo.com/v1/meteofrance?latitude=49.71&amp;longitude=4.16&amp;daily=sunset&amp;timezone=Europe%2FBerlin&quot; );
</code></pre>
<p>then it works.</p>
<p>I presume that I comes from network developper tools info in Chromium:</p>
<blockquote>
<p>Referrer Policy: strict-origin-when-cross-origin</p>
</blockquote>
<p>claiming a strict origin for zenquotes.io's API.
My esp server code being:</p>
<pre><code>void handleRoot(){
    srvAmb.sendHeader(&quot;Access-Control-Allow-Origin&quot;, &quot;*&quot;, 1);
    srvAmb.send(200,&quot;text/html; charset=utf-8&quot;, myRootWebPagWithJSExternalFetch);
}
</code></pre>
<p>Remark, with or without the additional 3rd param of sendHeader() it works.</p>
