Richard C.
—The JavaScript fetch
command is available in browsers and Node.js and enables a program to make an HTTP request. Even though you made an apparently valid request to a valid URL, you might still get an error like TypeError: Failed to fetch
.
First check the possible network causes if you haven’t already:
curl
?https
or http
and a trailing /
or not?http://host.docker.internal
as the URL and have you configured your network to see it?If the problem does not have a network solution, the most likely cause is a CORS (cross-origin resource sharing) error. Browsers and servers are wary of letting programs on one domain, subdomain, or port call those on another, as this is a security risk. For example, if you as a user browse a website, you don’t want any JavaScript that the site loads into your browser to be able to make calls to your bank account where you are logged in.
Web servers have CORS policies that specify what extra domains may make requests to the server. This is true whether you use a server you wrote, like in Node.js or Go, or a traditional server like Apache or Nginx. You need to configure CORS in any server that is called from a domain other than the one it hosts.
For example, if you run an Express.js server that returns Hello World!
in a GET method at http://localhost:3000
like this:
import express, { Request, Response } from 'express'; const app = express(); app.get('/', (req: Request, res: Response) => { res.send('Hello World!'); }); app.listen(port);
You’ll get an error if you call this URL in a fetch
command from a browser page on http://localhost:3001
because it’s using a different port from the server:
GET http://localhost:3000/ net::ERR_FAILED 200 (OK) Access to fetch at 'http://localhost:3000/' from origin 'http://localhost:3001' 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.
Note that the request succeeded with a response code of 200. However, the browser denies access to the content of the response since no CORS header was returned by the server.
Generally, you need to set only two CORS headers on your server to get fetch requests to work:
Access-Control-Allow-Credentials
: set this to true
if you use any cookies for authentication in your app that need to be passed to the server.Access-Control-Allow-Origin
: set this to a list of domains that you wish to allow access to your server.We can modify the example Express.js example above to have it return a usable response now:
import express, { Request, Response } from 'express'; const app = express(); app.get('/', (req: Request, res: Response) => { res.setHeader('Access-Control-Allow-Credentials', 'true'); if (req.headers.origin && ['http://localhost:3000', 'http://localhost:3001'].includes(req.headers.origin)) { res.setHeader('Access-Control-Allow-Origin', req.headers.origin); } res.send('Hello World!'); }); app.listen(3000);
If you are using a server that you wrote in Go or Python you can set these headers programmatically in a similar way to the example above. Consult your web framework’s documentation on how to do this.
For traditional standalone servers with configuration files, setting headers can be poorly documented. We recommend asking AI for examples to get started, and reading this website, which has a list of servers and their configuration CORS settings.
You might have a web application in the browser that gets a CORS error when calling a server that you did not write, like a public API. Unless you can get the API developer to change their server’s CORS policy, there is nothing you can do to fix the problem.
However, it might be that their server is not meant to be called from the browser and is intended only for server-to-server communication. In that case, you need to write a method on your server that communicates with their server and get your browser application to call your server’s method instead of theirs. In this way, your server acts as a proxy between your user’s browser and the public server it wants to contact. This will avoid the CORS error because your server can ignore it, unlike a web browser.
Be careful when enabling CORS on your server that you do not inadvertently allow attackers to make fraudulent calls to your users’ accounts on their behalf. To be sure your application is protected, add anti-CSRF tokens (cross-site request forgery) to all forms in your application. If the token submitted by a request does not match the one you generated for the user on the page, then the request must be rejected.
Please read this MDN article on CORS for more detailed information.
Tasty treats for web developers brought to you by Sentry. Get tips and tricks from Wes Bos and Scott Tolinski.
SEE EPISODESConsidered “not bad” by 4 million developers and more than 100,000 organizations worldwide, Sentry provides code-level observability to many of the world’s best-known companies like Disney, Peloton, Cloudflare, Eventbrite, Slack, Supercell, and Rockstar Games. Each month we process billions of exceptions from the most popular products on the internet.
Here’s a quick look at how Sentry handles your personal information (PII).
×We collect PII about people browsing our website, users of the Sentry service, prospective customers, and people who otherwise interact with us.
What if my PII is included in data sent to Sentry by a Sentry customer (e.g., someone using Sentry to monitor their app)? In this case you have to contact the Sentry customer (e.g., the maker of the app). We do not control the data that is sent to us through the Sentry service for the purposes of application monitoring.
Am I included?We may disclose your PII to the following type of recipients:
You may have the following rights related to your PII:
If you have any questions or concerns about your privacy at Sentry, please email us at compliance@sentry.io.
If you are a California resident, see our Supplemental notice.