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.

Nhan
  • 3,595
  • 6
  • 30
  • 38
TaylorOtwell
  • 7,177
  • 7
  • 32
  • 42

9 Answers9

47

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

user1469734
  • 851
  • 14
  • 50
  • 81
  • 1
    Thank you. Works fine in Firefox. Do you have anymore information about this bug? – TaylorOtwell Jan 13 '14 at 23:17
  • 7
    Not really a bug, but more something because of security reasons. See: http://stackoverflow.com/questions/3102819/chrome-disable-same-origin-policy – user1469734 Jan 14 '14 at 08:38
  • 1
    I tried in other browser and it worked @_@ Why chrome so mean :( – Bruno Gomes Aug 12 '14 at 14:30
  • 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? – Donald N. Mafa Jun 18 '15 at 18:26
  • 1
    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. – Paul Okeke Aug 09 '15 at 09:07
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.

  • 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. – Chris Rae Apr 14 '16 at 04:23
  • That is true, @ChrisRae. – Rui Afonso Pereira Apr 14 '16 at 11:03
  • This extension appears to be eliminate the error. However when I checked the request header it adds Origin: http://evil.com. I don't know if this is harmful or insignificant. – Isaac Pak Oct 24 '16 at 21:20
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'
Gabriel
  • 1,890
  • 1
  • 17
  • 23
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.

brain_bacon
  • 1,120
  • 11
  • 16
  • 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! – charltones Jan 19 '16 at 00:08
  • @charltones 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. https://code.google.com/p/chromium/issues/detail?id=343707 – brain_bacon Jan 19 '16 at 02:05
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>
Dawie Strauss
  • 3,706
  • 3
  • 23
  • 26
nkharche
  • 917
  • 9
  • 10
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.

David Hansen
  • 2,857
  • 2
  • 21
  • 19
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.

tacticurv
  • 498
  • 4
  • 18
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');
            }
        }
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