10

XMLHttpRequest cannot load http://192.168.1.253:8080/... No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:4200' is therefore not allowed access. The response had HTTP status code 401.

Pretty common error, with a great many possible solutions that haven't worked. I understand (I think) how CORS is supposed to work, and I don't see anything wrong with my HTTP headers, but it still doesn't work

From Chrome:

Request URL:http://192.168.1.253:8080/... Request Method:OPTIONS Status Code:200 OK Remote Address:192.168.1.253:8080 Referrer Policy:no-referrer-when-downgrade Response Headers Access-Control-Allow-Headers:x-requested-with,accept,content- type,authorization Access-Control-Allow-Methods:POST, GET, PUT, PATCH, OPTIONS, DELETE Access-Control-Allow-Origin:* Access-Control-Max-Age:3600 Allow:GET, HEAD, POST, PUT, DELETE, TRACE, OPTIONS, PATCH Cache-Control:no-cache, no-store, max-age=0, must-revalidate Connection:keep-alive Content-Length:0 Date:Mon, 15 May 2017 21:50:55 GMT Expires:0 Pragma:no-cache Server:... X-Content-Type-Options:nosniff X-Frame-Options:DENY X-XSS-Protection:1; mode=block Request Headers Accept:*/* Accept-Encoding:gzip, deflate, sdch Accept-Language:en-US,en;q=0.8 Access-Control-Request-Headers:authorization,content-type Access-Control-Request-Method:GET Cache-Control:no-cache Connection:keep-alive Host:192.168.1.253:8080 Origin:http://localhost:4200 Pragma:no-cache Referer:http://localhost:4200/... User-Agent:Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/57.0.2987.133 Safari/537.36 

My understanding is the OPTIONS response needs the Access-Control-Allow-Origin header set and allow the method type and header values, which it does

Relevant angular below. I've done a fair number of different combinations of this with all sorts of different stuff in the header, but nothing works

private getObject<T>(path: string): Promise<T> { return this.http.get(SERVER_URL + path, this.authenticationToken()) .toPromise() .then(response => response.json() as T) .catch(this.handleError); } private authenticationToken() : RequestOptions { let login = JSON.parse(sessionStorage.getItem('currentLogin')); if (login && login.authenticationToken) { let headers = new Headers({ 'Authorization': 'Basic ' + login.authenticationToken, 'Content-type': 'application/json', }); return new RequestOptions({ headers: headers }); } } 

I got the feeling I'm missing something obvious but it's driving me nuts, any help is appreciated. Note this does work with a pre-existing Ember application so I don't think it's the server

5
  • 1
    When you try Access-Control-Allow-Origin:localhost:4200 - explicitly put the url instead of * - does it work? Commented May 15, 2017 at 22:45
  • 1
    It's actually not your frontend or your requests. Your backend would need to be configured to allow CORS access. What you're getting back is actually a security measure by Chrome. I'm not saying it will solve all of your problems (401), but until you figure out how to configure CORS on your backend, this is a nice extension to tell Chrome to shut up: chrome.google.com/webstore/detail/allow-control-allow-origi/… Commented May 15, 2017 at 22:53
  • @Eeks33 afraid not Commented May 15, 2017 at 23:02
  • @joh04667 Thanks for the plugin, though i don't see how it could be the backend since it works with a different application Commented May 15, 2017 at 23:03
  • Since this is related to the backend server, you need to identify the technology it is running on and post/tag accordingly. Angular code is only client side requests and hence nothing to do with CORS Commented Apr 11, 2018 at 12:46

2 Answers 2

12

The response had HTTP status code 401.

401 indicates an authentication error. The error message in the question isn’t for a response from a preflight OPTIONS request. It instead seems to be for the actual GET request you’re trying to send.

So based on that error message, it seems the most likely scenario is that the browser’s preflight OPTIONS request succeeded but your GET request is not succeeding due to authentication failure.

So the server’s returning a 401 response/error page. And many/most web servers aren’t configured to send the Access-Control-Allow-Origin response header for error responses/pages. That’s the only reason you’re also getting a message about that header being missing.

But that missing header for the error response is not the cause of your problem; instead, the 401 is.

So it seems you probably want to figure out what’s causing the server to send a 401 response—why you’re getting an authentication failure. If you fix that it seems likely you’ll get a response from the server that includes the Access-Control-Allow-Origin response header as expected.

Sign up to request clarification or add additional context in comments.

Comments

9

This is a typical error found when we work with Angular and Ionic, the problem appears because when your app loaded in a browser on your app loads all the content from an origin that comes from your local address http://localhost:4200, then when you want to make any AJAX request sent out to another host than localhost:4200 the request is called from an any point different from the origin its require a CORS(Cross Origin Resource Sharing) preflight request to see if it can access the resource.

The solution is use a Proxy To Backend, with this you can highjack certain urls and send them to a backend server. The implementation is easy:

1.- Create a file proxy.conf.js in the root folder of your project.

2.- Configure your proxy, inside your proxy.conf.js file put this, assuming your new host is in http://localhost:3000.

const PROXY_CONFIG = [ { context: [ "/my", "/many", "/endpoints", "/i", "/need", "/to", "/proxy" ], target: "http://localhost:3000", secure: false } ] module.exports = PROXY_CONFIG;

3.- Modify your package.json file, inserting this "start": "ng serve --proxy-config proxy.conf.js",

4.- In your Service change a little the path of your request from this http://localhost:3000/endpoints/any/path/that/you/use to this ../endpoints/any/path/that/you/use(assuming the another host is in localhost:3000 and the context is /endpoints).

5.- Run angular since the root folder with: npm start ; this execute ng serve with the proxy parameters.

If you need more information about this please check the Proxy to backend Angular Cli documentation

3 Comments

Please don't post identical answers to multiple questions. Post one good answer, then vote/flag to close the other questions as duplicates. If the question is not a duplicate, tailor your answers to the question.
Why this line has .js instead of .json ? - 3.- Modify your package.json file, inserting this "start": "ng serve --proxy-config proxy.conf.js",
This is a "js" file beacause the configuratiosn are exported with Module exports, node js is interpreting this configuration as a constant while is running the "start" script.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.