AngularJS not detecting Access-Control-Allow-Origin header?
Asked Answered
U

9

45

I am running an angular app on a local virtualhost (http://foo.app:8000). It is making a request to another local VirtualHost (http://bar.app:8000) using $http.post.

$http.post('http://bar.app:8000/mobile/reply', reply, {withCredentials: true});

In the Network tab of Chrome Developer Tools I of course see the OPTIONS request, and the response includes the header:

Access-Control-Allow-Origin: http://foo.app:8000

However, the POST request is cancelled with the following error:

No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://foo.app:8000' is therefore not allowed access.

Has anyone experienced this? The Access-Control-Allow-Origin header is very plainly included in the response of the OPTIONS request, so I can't for the life of me figure out why the POST is acting the header was missing.

Access-Control-Allow-Credentials is also set to true.

Ulphia answered 13/1, 2014 at 22:30 Comment(2)
do you see Access-Control-Allow-Methods header on OPTIONS response?Genitor
Indeed. Allowing all methods.Ulphia
D
47

It's a bug in chrome for local dev. Try other browser. Then it'll work.

Doorpost answered 13/1, 2014 at 22:58 Comment(5)
Thank you. Works fine in Firefox. Do you have anymore information about this bug?Ulphia
Not really a bug, but more something because of security reasons. See: #3103319Doorpost
I tried in other browser and it worked @_@ Why chrome so mean :(Nickerson
What are you supposed to do when you are ready to deploy the application for a bigger audience to use, most people use Chrome, what is the correct way to handle this issue?Mavilia
This isn't a solution though!!! This has to do with CORS and not just browsers... Its a security constraint. You can always enable CORS on your server.Lulalulea
I
26

There's a workaround for those who want to use Chrome. This extension allows you to request any site with AJAX from any source, since it adds 'Access-Control-Allow-Origin: *' header to the response.

As an alternative, you can add this argument to your Chrome launcher: --disable-web-security. Note that I'd only use this for development purposes, not for normal "web surfing". For reference see Run Chromium with Flags.

As a final note, by installing the extension mentioned on the first paragraph, you can easily enable/disable CORS.

Illustrational answered 20/9, 2014 at 10:59 Comment(3)
An extra bonus is that this very useful plugin also happens to stop Facebook from working so, if your software development workflow resembles mine, you will likely finish the rest of what you were working in in record time.Paschall
That is true, @ChrisRae.Illustrational
This extension appears to be eliminate the error. However when I checked the request header it adds Origin: evil.com. I don't know if this is harmful or insignificant.Orthoepy
Y
7

I was sending requests from angularjs using $http service to bottle running on http://localhost:8090/ and I had to apply CORS otherwise I got request errors like "No 'Access-Control-Allow-Origin' header is present on the requested resource"

from bottle import hook, route, run, request, abort, response

#https://github.com/defnull/bottle/blob/master/docs/recipes.rst#using-the-hooks-plugin

@hook('after_request')
def enable_cors():
    response.headers['Access-Control-Allow-Origin'] = '*'
    response.headers['Access-Control-Allow-Methods'] = 'POST, GET, OPTIONS, PUT'
    response.headers['Access-Control-Allow-Headers'] = 'Origin, X-Requested-With, Content-Type, Accept'
Yvette answered 6/3, 2014 at 2:17 Comment(0)
T
3

I experienced this exact same issue. For me, the OPTIONS request would go through, but the POST request would say "aborted." This led me to believe that the browser was never making the POST request at all. Chrome said something like "Caution provisional headers are shown" in the request headers but no response headers were shown. In the end I turned to debugging on Firefox which led me to find out my server was responding with an error and no CORS headers were present on the response. Chrome was actually receiving the response, but not allowing the response to be shown in the network view.

Tucci answered 13/2, 2014 at 22:0 Comment(2)
Thanks - you got me on my way to fixing my own issue. I had the same symptoms. In my case I was using Amazon API gateway and calling it from AngularJS from within Chrome. I was missing a parameter, same as @tacticurv suggests but Chrome was implying it had never made the POST because of CORS when the OPTIONS request clearly succeeded. The extra gotcha I found was that API gateway's helpful "enable CORS" button doesn't do a complete job. It only added headers to the 200 OK responses and missed them from 400 and 500 error responses. These errors were then missed from the chrome inspector!Blanchard
@Blanchard Actually since I posted that answer I've been using chrome://net-internals/#events to detect errors like this instead of using Firefox. Just handy to know in the future. I actually did send a bug to Chromium and it was fixed for a while, but I think they reverted it. code.google.com/p/chromium/issues/detail?id=343707Tucci
A
3

CROS needs to be resolved from server side.

Create Filters as per requirement to allow access and add filters in web.xml

Example using spring:

Filter Class:

@Component
public class SimpleFilter implements Filter {

@Override
public void init(FilterConfig arg0) throws ServletException {}

@Override
public void doFilter(ServletRequest req, ServletResponse resp,
                     FilterChain chain) throws IOException, ServletException {

    HttpServletResponse response=(HttpServletResponse) resp;

    response.setHeader("Access-Control-Allow-Origin", "*");
    response.setHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS, DELETE");
    response.setHeader("Access-Control-Max-Age", "3600");
    response.setHeader("Access-Control-Allow-Headers", "x-requested-with");

    chain.doFilter(req, resp);
}

@Override
public void destroy() {}

}

Web.xml:

<filter>
    <filter-name>simpleCORSFilter</filter-name>
    <filter-class>
        com.abc.web.controller.general.SimpleFilter
    </filter-class>
</filter>
<filter-mapping>
    <filter-name>simpleCORSFilter</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>
Adventitious answered 20/6, 2015 at 7:26 Comment(0)
D
2

I just ran into this problem today. It turned out that a bug on the server (null pointer exception) was causing it to fail in creating a response, yet it still generated an HTTP status code of 200. Because of the 200 status code, Chrome expected a valid response. The first thing that Chrome did was to look for the 'Access-Control-Allow-Origin' header, which it did not find. Chrome then cancelled the request, and Angular gave me an error. The bug during processing the POST request is the reason why the OPTIONS would succeed, but the POST would fail.

In short, if you see this error, it may be that your server didn't return any headers at all in response to the POST request.

Diaspore answered 31/1, 2014 at 23:43 Comment(1)
This was essentially the problem I was having - thanks for the heads up.Pregnant
E
2

It can also happen when your parameters are wrong in the request. In my case I was working with a API that sent me the message

"No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'null' is therefore not allowed access. The response had HTTP status code 401."

when I send wrong username or password with the POST request to login.

Epley answered 26/9, 2015 at 3:40 Comment(0)
B
2

Instead of using $http.get('abc/xyz/getSomething') try to use $http.jsonp('abc/xyz/getSomething')

     return{
            getList:function(){
                return $http.jsonp('http://localhost:8080/getNames');
            }
        }
Boloney answered 30/3, 2016 at 23:27 Comment(0)
S
0

If you guys are having this problem in sails.js just set your cors.js to include Authorization as the allowed header

/***************************************************************************
  *                                                                          *
  * Which headers should be allowed for CORS requests? This is only used in  *
  * response to preflight requests.                                          *
  *                                                                          *
  ***************************************************************************/

  headers: 'Authorization' // this line here
Superelevation answered 17/11, 2015 at 5:32 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.