We are big fans of AngularJS here at Arroyo Labs, and often our Angular Apps require a lot of AJAX to work: a simple GET request to load data here, a form POST there. You know, typical web stuff.
More than once we’ve made an App that needs to make an AJAX request to a different domain than the one our app lives on and hit some roadblocks. For one, your browser doesn’t really allow it (I’ll explain this later) and for the most part it’s a pain compared to hitting a local resource.
“Why would you need to do that? Why aren’t you making locally hosted APIs to access this data?!” you may blurt out while reading this. Well sometimes, you have to.
Sometimes you run into a weird legacy architecture or you can’t access the backend code. You may even want to do all of this work with only front-end level code. What if you need the client’s browser to resolve a domain for you? It’s also possible you have been making AJAX requests to other domains and never encountered an issue until now.
The point is, eventually you will have to make an AJAX request on another domain, so lets talk about it.
The Same Origin Policy
The Same Origin Policy is a security feature built into your browser (and most everybody else’s) for your safety. It prevents scripts from accessing anything outside of the current ‘site’ as the executed script, and by site I mean the same Scheme + Hostname + Port as the page executing the script.
Take a look at this chart from the wikipedia page, for a script executing from http://www.example.com/dir/page.html
You can’t even make a request to a subdomain like http://foobar.example.com without Same Origin stepping in and waving its finger in your face. Try it, and check your console log: “not allowed by Access-Control-Allow-Origin"
all over the place.
Why does this policy exist? Imagine an internet where we could access any domain’s HTML or make a POST ‘on your behalf’ (to websites you are logged into like your bank or twitter) from your browser with Javascript. Thats a scary place.
So, how do we get around the Same Origin Policy?
Theres a few ways to ‘relax’ the Same Origin Policy so you can actually interact with data from another domain.
1) CORS
Introduced relatively recently are a type of headers that tell your browser its ok with a requests from another domain. This is known as Cross Origin Resource Sharing or CORS. With these headers turned on, you can make POST & GETs just like you would with an endpoint on the same server as your script.
You will need access to the webserver configuration to make this happen, which is not an option for a site you have no control over. The guys over at enable-cors.org do a good job explaining how to enable this for the most common webservers.
Also, I should note, this is the only method that allows you to send a POST request to another domain.
In fact, here is our example
2) Proxy (with CORS)
This solution involves a middle man proxy that does have a CORS headers that passes along your request to a server that does not have CORS headers. Yes, this is a hack-y way to just make a cURL call to a webservice.
There is the hosted flavor (which is inherently unsafe, since they can see/log everything you send) or the self hosted variety.
3) JSONP
This is the most common way to make a GET request to another domain, and is probably the method with the least effort required.
The “P” in the JSONP actually stands for padding, which really means “Named Function”. You pass along a named javascript function that tells the server to wrap its response and when it responds your data is neatly wrapped with a helper function. This gets around the Same Origin Policy since <script> tags are ok’d for cross domain execution, which is how we can include JS libs from CDNs and other sources.
This method does require control over the request destination, or the site itself has to support a JSONP callback. This is just a javascript function returned from a ‘black box’, so there are some serious security concerns (but you’re not sending sensitive data via GET, right?). Also, we should note that this method have VERY limited support for reporting errors. Most people work around this by timing a response check and timeouts.
This method isn’t really possible with the $http object (the traditional way to make AJAX requests with AngularJS), but it’s still a viable option for some cross domain communication. I think it’s an interesting concept worth exploring and I think would be a cool way to explore promises and error states.
Conclusion
With some work and concessions, you can make cross domain requests. We’ll provide some working code examples soon.
Tags: angular, crossdomain, HTTP, sameoriginpolicy, xdomain
Categories: JavaScript, Programming
Lets talk!
Join our mailing list, we promise not to spam.