Quick Tip: Cross Domain AJAX Request with YQL and jQuery
videos

Quick Tip: Cross Domain AJAX Request with YQL and jQuery

Tutorial Details
  • Technologies: YQL, jQuery, Regular Expressions
  • Difficulty: Moderate
  • Length: 8 Minute Video
Share

For security reasons, we cannot make cross-domain AJAX requests with jQuery. For example, I can’t call the load() method, and pass in ‘cnn.com’. As we’d be loading in scripts and such, as well as our desired content, this would present a significant security risk. Nonetheless, there may be times when this is specifically what you require. Thanks to YQL, we can allow for this functionality rather easily!

The Script

// Accepts a url and a callback function to run.
function requestCrossDomain( site, callback ) {

	// If no url was passed, exit.
	if ( !site ) {
		alert('No site was passed.');
		return false;
	}

	// Take the provided url, and add it to a YQL query. Make sure you encode it!
	var yql = 'http://query.yahooapis.com/v1/public/yql?q=' + encodeURIComponent('select * from html where url="' + site + '"') + '&format=xml&callback=?';

	// Request that YSQL string, and run a callback function.
	// Pass a defined function to prevent cache-busting.
	$.getJSON( yql, cbFunc );

	function cbFunc(data) {
	// If we have something to work with...
	if ( data.results[0] ) {
		// Strip out all script tags, for security reasons.
		// BE VERY CAREFUL. This helps, but we should do more.
		data = data.results[0].replace(/<script[^>]*>[\s\S]*?<\/script>/gi, '');

		// If the user passed a callback, and it
		// is a function, call it, and send through the data var.
		if ( typeof callback === 'function') {
			callback(data);
		}
	}
	// Else, Maybe we requested a site that doesn't exist, and nothing returned.
	else throw new Error('Nothing returned from getJSON.');
	}
}

Call the Function

requestCrossDomain('http://www.cnn.com', function(results) {
   $('#container').html(results);
});

Stripping Out the Script Tags

I had to progress rather quickly in the video, so perhaps the regular expression that strips out the <script> tags require further detail.

XEROX CODE
.replace(/<script[^>]*>[\s\S]*?<\/script>/gi, '');

When we load our desired page, it’s also going to load scripts! You must be very careful when making cross domain request. It definitely helps to strip out the <script> tags, but you should do more in an actual project.

Let’s take the regular expression step by step.

<script[^>]*>

Find all open script tags; however, they could come in many forms: <script type=”text/javascript” src=”bla.js”></script> , or <script type=”text/javascript”>lots of code here…</script> . For this reason, we add a character class ( [^>]* ), which mean, “Find zero or more of anything that IS NOT a closing bracket. This will take care of the attributes and values.

[\s\S]*?

Next, we want to strip out all code, as well as any spacing. \s refers to a space. \S refers to anything that IS NOT a space. Once again, we add a * after the character class to designate that we want zero or more occurrences.

<\/script>

Finally, find the closing script tags.


Further Reading

This is only meant to provide a glimpse of how we can achieve this functionality. Only so much can be covered in a five minute video. Feel free to discuss in the comments, and you’re always encouraged to fork the source code to improve upon it!

Related Posts

Add Comment

Discussion 39 Comments

  1. john says:

    very nice, I was always wondering how to do something like this, thanks.

  2. Drazen Mokic says:

    Man i hate youtube when i`m watching tutorials becouse of the poor quality the videos have -.-

    I subsrcibed know on youtube but it keeps telling me “This video is private”. Someone help? :)

    • Jeffrey Way says:

      It’s a bug with YouTube right. Bunches of people are complaining about it.

      The Nettuts+ videos on YouTube should still display pretty well. Just make sure that you select the 720 or 1080 option to view in HD.

      The embeds on Nettuts+ should automatically begin playing in HD.

      • Anto says:

        Should just stick with screenr. No fuss, no mess.

      • Jeffrey Way says:

        The bug has been fixed. The video will play now. :)

      • Drazen Mokic says:

        If i switch to 720 it is even worse. Its really horrible, letters are quite impossible to read. I tested in Firefox and Google Chrome. Is someone else having the same issues or is this a bad configuration (whatever it could be) on my side?

        ps: The video is still not working :(

      • Drazen Mokic says:

        Error Message (Translated from German):

        This video is private. If this video was sent to you, you have to accept the “senders” request.

        Bug 2 xD

        The comments form does not remember my information (name, email, url) but cookies are turned on.

      • Jeffrey Way says:

        @Drazen – Sounds like you’re viewing at the lowest resolution. When you watch the video above, does it say 1080 in the video (lower right)? It should. For me, it’s displaying really well.

      • Jeremy says:

        Same here, quality is absolutely terrible, and also worse here at 720, I really hope you can go back to screenr, or offer extra ways, because even full screen on my macbook in safari it’s pretty difficult to read the code

      • Jeffrey Way says:

        @Drazen – I just checked, and am pretty sure that YouTube has fixed the problem. You shouldn’t need to sign-in/sign-up to view it.

      • Jeffrey Way says:

        This is really strange. Are you guys viewing full screen? I’m not experiencing this blurriness at all.

    • Drazen Mokic says:

      Ok now its works! On 1080 the quality is really good, nice. Maybe i am starting to like YT. (On 720 it`s still ugly).

      • Jeremy says:

        Agreed, same here, looks pretty good now that I checked. I was going by the “How to Change your Website’s Background with Each WordPress Post” post because the new one wasn’t showing up for me and that looked bad even at 720, but the new one looks good. Thanks

      • Drazen Mokic says:

        Yes, all the older videos look really horrible on 720 for me.

        Example: http://tinyurl.com/yafcecb

      • Jeffrey Way says:

        Ok – just saw what you’re referring to. Must be another YouTube issue. So you load that page, enter full screen, and then change the resolution to 720. Then, it displays really badly right? Trying switching out of full screen, and right back into it. The display should fix itself.

        That’s really weird! Just watch the auto-HD videos on Nettuts+. ;) I’ll also add Screenr/Blip versions when applicable.

  3. Daniel says:

    Huh, YouTube is too buggy. Please try Vimeo or Blip.

  4. Jonathan says:

    Using jquery to do a callback this way busts YQLs caches and hurts your performance. Please take a look at the caching blog entry we posted recently on yqlblog.net

  5. CK says:

    I am getting an “An error has occurred. Try again later.” in the embedded clip above.

  6. Crysfel says:

    Awesome! I didn’t know about this, thanks you! :)

  7. Matt says:

    Is there a way to change the client headers? I’m wanting to make a forum reader using this but they’ve disallowed all bots via robots.txt and YQL doesn’t like this…

  8. Learning something new every day, thanks for the tutorial.

  9. Matt says:

    Thanks for the tutorial, i’ve been hearing lots about YQL as Christian Heilmann has mentioned it quite a lot in his tweets. This is a perfect introduction.

  10. Lou says:

    now if only there were a way to post to a different domain….sigh

  11. Joy says:

    Thanks, that was a good intro to YQL. I’d previous solved the cross-domain loading by using PHP to download the content I need, and reading the results using jQuery.

    I read the blog entry Jonathan pointed out, and realized that some applications really can’t cache, especially if they’re gathering real-time data that really can change every ten seconds. Maybe those apps shouldn’t use this particular solution (because it whales on Yahoo servers)?

    Really useful tutorial!

  12. Richard says:

    YouTube Eh? If that’s the future of Nettuts+ then that is unfortunate. I watch these at work and will no longer be able to view them if they are all YouTube.

  13. Tal Ater says:

    I created something very similar to this a few weeks ago, and after running for a few days, YQL started blocking our query…

    It didn’t matter that we never passed YQL’s query limits, and cached everything that could be cached…We still got blocked.

    We had to rewrite the whole thing to be done on our server with PHP.

  14. Chad says:

    Wow, only if i had found this a six months ago for a project i was working on.

  15. Khaled says:

    well youtube doesn’t work here in my country

  16. adrian says:

    There’s a cross domain ajax library called cows ajax http://cows-ajax.sourceforge.net/tech.php

  17. alex says:

    like to make an ajax/jquery tutorial request: how to make the back browser button to work correctly in a filter search ->result page->detail page->result page

    kind regards

  18. Andrew says:

    Actually it is possible to make a cross-domain AJAX request with Jquery alone for $.getJSON requests. I do it all the time. The Jquery site even has an example of a remote call in the documentation: http://api.jquery.com/jQuery.getJSON/

  19. leo says:

    Nice article, as usual !

    I always thought cross-domain ajax wasn’t allowed: I’m wondering how does using getJSON changes that…

    Any idea ? If I wanted to create some API that could be called by cross-domain Ajax, what should I do ? Returing JSON is enough ?

  20. benroe says:

    how can i make 3 or 4 request in a loop? one after another

  21. George says:

    Hello there,
    That’s a really goog article.

    I’m trying to use your script to retrieve an Oauthenticated query using as passing “yql” value a signed one returned by the function of the followinbg script -> http://paul.donnelly.org/2008/10/31/2-legged-oauth-javascript-function-for-yql/ script, but unseccesfull.

    I wonder if you or somebody else know the reason of not working or any alternative way to use Cross Domain AJAX Request with YQL and jQuery using an authenticated query.

    Thank you very much.

    Regards,
    George K.

  22. faressoft says:

    This is a great tutorial, Thank you very much.

    but how can i get all content not only

Add a Comment

To add a code snippet to your comment, please wrap your code like so: <pre name="code" class="html">YOUR CODE</pre>. You can replace the class name with "js," "css," "sql," or "php." If there are any "<" or ">" within your code, please search and replace them with: &lt; and &gt; respectively.