spenibus.net
2014-07-11 18:48:02 GMT

Javascript/PHP - Bypassing the cross-origin restriction for XMLHttpRequest

I was harshly reminded of the cross-origin restriction imposed by XMLHttpRequest the other day when I decided to create a small dashboard for Twitch to keep an eye on viewers and live status without loading the actual Twitch dashboard. The idea was to have a local script rather than a web-based page, calling the Twitch API and update the display at a regular interval. Of course, loading a page via `file:///` offers very little similarity to the domain twitch.tv and my XMLHttpRequest calls went unanswered for security reasons. I was reluctantly considering a web-based approach when a more versatile idea formed in my mind. It is possible to access a cross-origin resource if it is explicitly allowed by the server using the following header: Access-Control-Allow-Origin: * I then wrote a small PHP script that would act as a proxy between the actual resource and the script, relaying the content verbatim and adding the aforementioned header: ```` /******************************************************************* read url */ if($_GET['key'] == 'secret' && mb_strlen($_GET['url']) > 0) { header('Access-Control-Allow-Origin: *'); readfile($_GET['url'], false); } ```` The key serves as a password to avoid unwanted use of the script by third parties. Allowing POST requests could also be an improvement. It is now possible to use XMLHttpRequest locally as follows: ```` var url = 'http://domain.tld/urlReader.php?key=secret&url='+encodeURIComponent('https://api.twitch.tv/kraken/channels/username'); var xhr = new XMLHttpRequest(); xhr.onload = handlerFunc; xhr.open("get", url, true); xhr.send(); ```` PHP will send the new header, then fetch the document and output it right away. Although remember, this will obviously invalidate certain services like geolocation, since the remote server will see your php server instead of your actual machine. As usual, this solves an issue specific to me but it could always help someone else.