I spent the last 3 days studying how to make a cross domain request using XMLHttpRequest. The best alternative is indeed with JSONP which I am already using.
But I still
This happens because the same origin policy is applied on the client side (browser) by evaluating the following access control header values returned from the server:
As you can see, the request must first be completed on the server in order for the browser to inspect the returned headers. This is exactly the reason why your request execute on the server.
You can have a look at Priciples of the Same-Origin Policy by A. Barth.
See bobince's answer at a similar question:
As per XMLHttpRequest level 2, browsers allow cross-origin GETs to be sent without preflighting, but don't allow the results to be read from the response unless the remote domain opts in. There is no additional vulnerability here because you can already cause a GET to an arbitrary URL to be sent (including query string, for what it's worth) through multiple more basic interfaces.
For example you have always been able to create an element with its src set to an address on a remote domain; taking away that cross-domain ability would break a lot of the existing web.
Related: