I'm trying to setup AngularJS to communicate with a cross-origin resource where the asset host which delivers my template files is on a different domain and therefore the XHR request that angular performs must be cross-domain. I've added the appropriate CORS header to my server for the HTTP request to make this work, but it doesn't seem to work. The problem is that when I inspect the HTTP requests in my browser (chrome) the request sent to the asset file is an OPTIONS request (it should be a GET request).
I'm not sure whether this is a bug in AngularJS or if I need to configure something. From what I understand the XHR wrapper can't make an OPTIONS HTTP request so it looks like the browser is trying to figure out if is "allowed" to download the asset first before it performs the GET request. If this is the case, then do I need to set the CORS header (Access-Control-Allow-Origin: http://asset.host...) with the asset host as well?
This fixed my problem:
OPTIONS request are by no means an AngularJS bug, this is how Cross-Origin Resource Sharing standard mandates browsers to behave. Please refer to this document: https://developer.mozilla.org/en-US/docs/HTTP_access_control, where in the "Overview" section it says:
It is very hard to provide a generic solution that would work for all the WWW servers as setup will vary depending on the server itself and HTTP verbs that you intend to support. I would encourage you to get over this excellent article (http://www.html5rocks.com/en/tutorials/cors/) that has much more details on the exact headers that needs to be sent by a server.
Somehow I fixed it by changing
to
Perfectly described in pkozlowski's comment. I had working solution with AngularJS 1.2.6 and ASP.NET Web Api but when I had upgraded AngularJS to 1.3.3 then requests failed.
Solution for Web Api server was to add handling of the OPTIONS requests at the beginning of configuration method (more info in this blog post):
If you are using Jersey for REST API's you can do as below
You don't have to change your webservices implementation.
I will explain for Jersey 2.x
1) First add a ResponseFilter as shown below
2) then in the web.xml , in the jersey servlet declaration add the below
I gave up trying to fix this issue.
My IIS web.config had the relevant "
Access-Control-Allow-Methods
" in it, I experimented adding config settings to my Angular code, but after burning a few hours trying to get Chrome to call a cross-domain JSON web service, I gave up miserably.In the end, I added a dumb ASP.Net handler webpage, got that to call my JSON web service, and return the results. It was up and running in 2 minutes.
Here's the code I used:
And in my Angular controller...
I'm sure there's a simpler/more generic way of doing this, but life's too short...
This worked for me, and I can get on with doing normal work now !!