35

Cross-Origin Resource Sharing. Avoiding Access-Control-Allow-Origin CORS error

 5 years ago
source link: https://www.tuicool.com/articles/hit/r2ai2qF
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

In this article, we explain what Cross-Origin Resource Sharing ( CORS ) is and how to avoid errors associated with it and the Access-Control-Allow-Origin header. This includes describing it both from the viewpoint of the frontend and the backend.

CORS: Cross-Origin Resource Sharing

Cross-Origin Resource Sharing( CORS ) is a mechanism allowing (or disallowing) the resources to be requested from another origin than it is served on. It is built into the browsers and uses HTTP headers to determine whether or not it is safe to allow a cross-origin request. When a web application requests a source with a different origin (origin includes a domain, a protocol, and a port) it is cross-origin. Browsers restrict such requests unless the response from the other origin includes the right headers.

Let’s jump straight into coding. We use a simple Express app here:

const express = require('express');
 
const app = express();
 
app.get('/posts', function(req, res) {
  res.send([
    {
      id: 0,
      title: 'Lorem ipsum',
      content: 'Dolor sit amet',
      author: 'Marcin'
    },
    {
      id: 1,
      title: 'Vestibulum cursus',
      content: 'Dante ut sapien mattis',
      author: 'Marcin'
    }
  ]);
});
 
app.listen(8080);

This, when running locally, opens the http : //localhost:8080/posts endpoint.

So far so good. Now try to use Postman to perform a GET request.

36BzuqV.png!web

A success! Let’s modify our app a little and add an additional endpoint:

app.get('/', function(req, res) {
  res.send();
});

This will give us an empty document at the http : //localhost:8080 address. Let’s open it in the browser, and in DevTools execute:

fetch('http://localhost:8080/posts');

fYrAjqI.png!web

Works fine as well!

In this example, we run our request in the same origin, but this is often not the case. Imagine creating a frontend app that runs in a different origin, for example on a different port. To create such a situation, let’s run an additional express app on a different port.

const express = require('express');
 
const app = express();
 
app.get('/', function(req, res) {
  res.send();
});
 
app.listen(4200);

Now, let’s open our second app at the address http : //localhost:4200 and try to perform the same fetch request.

ANNRF3A.png!web

This results in an error:

Access to fetch at ‘http://localhost:8080/posts’ from origin ‘http://localhost:4200’ 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.

As you can see, the request itself was successful, but the browser blocked it.

Conclusions

  • The first example includes us using  Postman , so the CORS mechanism wasn’t involved
  • In the second example, we perform a request from the same origin, so the CORS mechanism didn’t block our request
  • The third example is a Cross-Origin request and therefore it is blocked.
    This does not need to be the case. As the error states, we can set the  Access-Control-Allow-Origin header. You need to attach it to the response that the browser receives from the server.

Access-Control-Allow-Origin header

To specify what origins have access to the resource, you need to add the Access-Control-Allow-Origin header to your response. It will be interpreted by the browser of the visitor of your site.

While using Express there are a few ways to do that. The simplest one is to attach the header straight in the handler:

app.get('/posts', function(req, res) {
  res.setHeader('Access-Control-Allow-Origin', 'http://localhost:4200');
  res.send([
    {
      id: 0,
      title: 'Lorem ipsum',
      content: 'Dolor sit amet',
      author: 'Marcin'
    },
    {
      id: 1,
      title: 'Vestibulum cursus',
      content: 'Dante ut sapien mattis',
      author: 'Marcin'
    }
  ]);
});

This will tell the browser that it is safe to request a resource from that origin.

uERV3uB.png!web

It works! But that means that you would have to call setHeader in the every one of your handlers. This is where you can use middleware :

app.use(function (req, res, next) {
  res.setHeader('Access-Control-Allow-Origin', 'http://localhost:4200');
  next();
});

If you call the use function, the callback you provide will be executed every time a request is sent to the server. It results in attaching the Access-Control-Allow-Origin header to all your responses.

Possible values

One of the possibilities is to specify an exact origin as we did in the previous example. If you choose to be specific, you need to all the way: browsers do not support multiple Access-Control-Allow-Origin   headers. On the other hand, you can use a wildcard :

res . setHeader ( 'Access-Control-Allow-Origin' , '*' ) ;

This value tells the browser that the given resource can be shared with any origin. There is one catch though: when using a wildcard , you can’t send or receive cookies. If you try to do so, the browser throws an error.

Other ways to bypass the CORS policy

One way to override the CORS policy is to install an extension such as  Allow-Control-Allow-Origin: * . It Adds the  Allow - Control - Allow - Origin : * header to the all the responses that your browser receives. As mentioned above, it disrupts the way that cookies are sent and received, so keep that in mind.

Another thing you can do is to specify in your request, that you want to bypass the CORS secure mechanism. You can do it if you use Fetch API by setting  the  mode parameter to  no-cors :

fetch('http://localhost:8080/posts', { mode: 'no-cors' });

This will work regardless of the  Access-Control-Allow-Origin header. There is no equivalent of that in the XMLHttpRequest, unfortunately.

If you would like to know more about Fetch API and XMLHttpRequest , check out  Comparing working with JSON using the XHR and the Fetch API

Summary

In this article, we explained what the Cross-Origin Resource Sharing ( CORS ) is, and how can we deal with it in terms of the origin access control. It included creating a simple backend express app and sending requests both from Postman and the browser to illustrate how the CORS works. Aside from that, the article provided tips on how to deal with this error by setting the  Access-Control-Allow-Origin header, using browser extensions and an additional parameter that you can set in the Fetch API request. This can help you design both your frontend and backend while keeping the CORS mechanism in mind.


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK