Welcome to a quick tutorial and example on how to perform a cross-origin fetch request in Javascript. Are you trying to do a fetch request to a different domain? Only to be denied with a “no Access-Control-Allow-Origin header is present” error?
To perform a cross-origin fetch call:
- Run the fetch call “as-it-is”, CORS is already enabled by default –
fetch("http://second-site.com/page.php");
- Set the
Access-Control-Allow-Origin
header on the second site accordingly –header("Access-Control-Allow-Origin: http://first-site.com");
Yes, it’s that simple. But let us walk through the exact steps on how to set up virtual hosts on the localhost for testing – Read on!
ⓘ I have included a zip file with all the source code at the start of this tutorial, so you don’t have to copy-paste everything… Or if you just want to dive straight in.
QUICK SLIDES
TABLE OF CONTENTS
DOWNLOAD & NOTES
Firstly, here is the download link to the example code as promised.
QUICK NOTES
- This tutorial is tested on a WAMP8 server only.
EXAMPLE CODE DOWNLOAD
Click here to download all the example source code, I have released it under the MIT license, so feel free to build on top of it or use it in your own project.
CORS FETCH WITH XAMPP
All right, let us now get into the example of setting up virtual hosts and running a CORS fetch – All on a local machine.
STEP 1) UPDATE THE HOSTS FILE
127.0.0.1 site-a.com
127.0.0.1 site-b.com
For the uninitiated – Don’t need to panic, all that is happening here is a manual DNS override. That is, http://site-a.com
and http://site-b.com
will now resolve to localhost 127.0.0.1
. If you are using IPV6, change that to ::1
instead.
P.S. Mac and Linux users, your hosts file is probably located at /etc/hosts
. Although that may differ for different builds and versions.
STEP 2) APACHE VIRTUAL HOST
# SITE-A.COM
<VirtualHost *>
DocumentRoot "C:/sitea/"
ServerName site-a.com
<Directory "C:/sitea/">
Options Indexes FollowSymLinks Includes ExecCGI
AllowOverride All
Require all granted
</Directory>
</VirtualHost>
# SITE-B.COM
<VirtualHost *>
DocumentRoot "C:/siteb/"
ServerName site-b.com
<Directory "C:/siteb/">
Options Indexes FollowSymLinks Includes ExecCGI
AllowOverride All
Require all granted
</Directory>
</VirtualHost>
- Next, we need to create 2 folders –
sitea/
andsiteb/
. - Edit
httpd-vhosts.conf
, create two virtual hosts forsite-a.com
andsite-b.com
– Map them to the respectivesitea/
andsiteb/
folder.
STEP 3) CROSS-ORIGIN FETCH REQUEST
<script>
function fetchCORS () {
fetch("http://site-b.com/cors.php")
.then((res) => { return res.text(); })
.then((txt) => { console.log(txt); });
}
</script>
<input type="button" value="Fetch Request" onclick="fetchCORS()"/>
Now that the virtual hosts are ready, let us create a simple HTML page to fire a cross-origin fetch request.
STEP 4) CROSS-ORIGIN ALLOW
<?php
// (A) THE LAZY WAY
header("Access-Control-Allow-Origin: *");
echo "It works!";
Finally, the laziest way to respond to cross-origin calls is to reply with Access-Control-Allow-Origin: *
. Yes, it works. But take note that it literally means any website can make a call to this script, and that makes it extremely vulnerable to attacks.
EXTRA) SMARTER CROSS-ORIGIN ALLOW
<?php
// (B) SMARTER WAY
// (B1) GET REQUEST ORIGIN
if (array_key_exists("HTTP_ORIGIN", $_SERVER)) {
$origin = $_SERVER["HTTP_ORIGIN"];
} else if (array_key_exists("HTTP_REFERER", $_SERVER)) {
$origin = $_SERVER["HTTP_REFERER"];
} else {
$origin = $_SERVER["REMOTE_ADDR"];
}
// (B2) ALLOWED DOMAINS
if (!in_array(
parse_url($origin, PHP_URL_HOST),
["localhost", "site-a.com", "site-b.com"]
)) {
http_response_code(403);
exit("$origin not allowed");
}
// (B3) PROCEED
header("Access-Control-Allow-Origin: $origin");
echo "It works!";
This is a slightly smarter and safer way to deal with cross-domain calls. We counter-check the origin of the request, and respond only if it is an “allowed domain”. While this is not 100% foolproof, it will not respond to everyone at the very least.
USEFUL BITS & LINKS
That’s all for the tutorial, and here is a small section on some extras and links that may be useful to you.
COMPATIBILITY CHECKS
Fetch is already well-supported across all modern browsers at the time of writing. But if you have to support legacy browsers – It is also possible to set CORS in XMLHttpRequest
.
LINKS & REFERENCES
- How to Edit Your Hosts File on Linux, Windows, and macOS – Linuxize
- Fetch API – MDN
INFOGRAPHIC CHEATSHEET

THE END
Thank you for reading, and we have come to the end. I hope that it has helped you to better understand, and if you want to share anything with this guide, please feel free to comment below. Good luck and happy coding!