3
votes

I am testing our Angular app (running at http://localhost:4200) against a local instance of our Node/Express/MongoDB-based API (which I'm running at http://localhost:3000).

One of the endpoints I'm testing is used to allow our in-house users to download a file. Now, on our actual API URL, we have our CORS policy set (see below for details) - and this is an internal office app run behind a VPN.

But when I try and test this download functionality on my local app running against a local instance of the API, I get this error message:

Access to XMLHttpRequest at 'http://localhost:3000/v0/filegenerator/download?emailDocId=47dh385686e780c18e905&apikey=9d98e41d-44e9-4bbb-ab3d-35b7df5272dc&token=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJDUkVXTWVtYmVyIjoiNWmNoIjoiU2MDc0ODd9.bA5B5bx4wPSSiVCS_LxTK1gifjtif8dj29sfUBHqpOg' from origin 'http://localhost:4200' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: It does not have HTTP ok status.

A couple of questions here:

1.) Is this a generic Chrome security error message?

2.) Is there a way I can turn this off, so I can test downloading the file? Or can I only test this by hitting our actual live API?

How can I best get around this in my testing environment?

Added note: I do have a CORS extension - "Allow-Control-Allow-Origin: * 1.0.3" - installed in Chrome, and it's currently set to "Enable Cross-Origin Resource Sharing".

Also, on our backend Node/Express environment, this is our current setting:

  app.use(function(req, res, next) {
    res.header("Access-Control-Allow-Origin", "*");
    res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");
    res.header("Access-Control-Allow-Methods", "PUT, POST, GET, DELETE, OPTIONS");
    return next();
  });
3
Simple way is, you have a chrome extension for cors so you can test it, but you should handle this better, extension is just a quick fixNemanja G
Saying "you should handle this better" is not helpful because it's so vague. If you're going to make that comment, please offer further detail. Also, I already have a CORS extension in Chrome, and it's set to "Enable Cross-Origin Resource Sharing".Muirik
I do not know exactly what you should do, but you should handle it on the backend somewhere, I just said you can use that extension as a quick fix until you find/someone offers a fix on the backend.Nemanja G
Already have the CORS Chrome extension. And I don't think there's anything you can do "on the backend" to handle this. I think it's a front-end browser issue. If not, details would be needed for me to know how to address it.Muirik
I am on a Mac, so I closed out Chrome, opened up my Terminal and ran: open -a Google\ Chrome --args --disable-web-security --user-data-dir. Seemed to do the trick.Muirik

3 Answers

1
votes

For testing purposes you can use chrome's disable-web-security flag.

  • Close all your chrome windows.
  • Run chrome.exe --disable-web-security
1
votes

CORS headers are basically a way for a server to say, "I recognize these other servers as sources to send me requests, and it should be safe for the browser." If there is no header present, then only requests that originate from the same server are considered safe.

You should be able to configure your local application to add a the header to the response.

The plain text header would look like Access-Control-Allow-Origin: localhost:4200

0
votes

That is a general security feature in browsers. You cannot turn it off. One way to get around this is to allow your origin on the server side, by setting the Access-Control-Allow-Origin header. However, this won't work for preflight (OPTIONS) requests, if you don't handle them separately.

If that is not possible (due to 3rd party libs, services, authentication, etc...) you could set up a reverse proxy in Angular, which allows you to tunnel all of your requests. To the browser it looks like your requests are sent to the same domain (and port) as your angular application (and therefore assume to have the same origin).

Just create a proxy.conf.js in your project like so:

const path = "/proxy_path/*";
const proxy = "/proxy_path/";

const pathRewrite = {};
pathRewrite["^" + proxy.slice(0, -1)] = "";

const configs = {
    target: 'your_service_url',
    secure: false,
    changeOrigin: true,
    pathRewrite,
    logLevel: "debug"
}

const PROXY_CONFIG = {};
PROXY_CONFIG[path] = configs;

module.exports = PROXY_CONFIG;

And use ng serve --host 0.0.0.0 --disable-host-check --proxy-config <PATH_TO_PROXY_CONF> to start it.

I hope this helps!