Using jQuery To Load Content Onto A Page Without An iFrame

iFrames can be a convinent way of loading content from one domain onto another, but they do have their limitations. For example, it usually isn't possible to style the contents of the iFrame and you are therefore left at the mercy of a third party site. They also look pretty shonky if the third party site does down for whatever reason. Displaying large "page not found" statements on your page is quite unsightly.

There is a function in jQuery called load() that will use an AJAX request to load content from page onto another, and can even extract specific areas of the page and return only those parts. I thought I would run through some examples and then show how it is possible to display content from another domain on a page. Lets say we have a PHP file on the server that generates a random number, this would be the following very simple code.

<?php
echo rand();

This can be loaded into a div on a page of HTML using a single call in jQuery that utilises the load() function. This will just grab the text from the random_number.php file (the contents of which is in the above example) and put the result in the div with the id of test. Here is a page of HTML that does just that. Note that if you want to run this you'll need to put it on a server to enable the AJAX calls, otherwise it won't do anything.

<!DOCTYPE HTML>
<html> 
    <head> 
        <title>Loader</title> 
        <script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.5.0/jquery.min.js"></script> 
        <script type="text/javascript">
            $(document).ready(function(){
                $('#test').load('/random_number.php', '', function(response, status, xhr) {
                    if (status == 'error') {
                        var msg = "Sorry but there was an error: ";
                        $(".content").html(msg + xhr.status + " " + xhr.statusText);
                    }
                });
            });
        </script> 
    </head>
    <body> 
        <div id="test"></div>
    </body>
</html>

Taking this a step further it is possible to get part of the text on a page by passing an extra bit of text to the load() function. The first parameter of the function is the location of the resource, but it is also possible to add a CSS identifier to the resource that will bring back only the block you were looking for. Take the following little HTML snippet, which would be loaded into a file called html_snippet.html on the server.

<div>Some <strong class="aclass">content</strong></div>

It is possible to grab the contents of just the "strong" element by adding a space and then the CSS selector you need to extract that bit of content, in this case it is ".aclass". This means we only need to change the jQuery example above a little bit to get this working.

$('#test').load('/html_snippet.html .aclass', '', function(response, status, xhr) {

The thing that separates iFrames from AJAX calls is that an iFrames can point anywhere, whereas an AJAX call MUST be on the same domain as the original file. This is a built in security feature of JavaScript and cannot be circumvented. This means we need to add a quick workaround to bypass this security mechanism. To take a realworld example I thought it might be a good idea to try and download some Google search results and print them onto the page. First we need to create the PHP code to download the Google search results, which is actually quite easy. Here we are searching for the term "wibble".

<?php
    $url = 'http://www.google.com/search?hl=en&q=';
    $output = file_get_contents($url . urlencode('wibble'));        
    echo $output;

Call this file something like searchgoogle.php and pop it on your server. We now need to update the jQuery so that we only display the search results and not all of the other stuff on the Google search results page that isn't needed. We do this by supplying the CSS selector "#res". Here is the updated line of code that you need to change. Once this is done the page automatically loads the test div with the search results for the term "wibble".

$('#test').load('/searchgoogle.php #res', '', function(response, status, xhr) {

Just loading the results onto the page when the DOM has loaded isn't quite the best way to do things in every situation, it is also nice to add a "Loading" graphic and a swishy effect when the content is changed to make things nice and pretty. This is all controlled via a link element at the top of the page. This requires a little bit more jQuery code to be added so I have printed it out in full again with the additional actions added. We are essentially adding a click event to the link element so that it will run the load() function. There are some other action and animation functions here that will cause the content to show and hide at different times, but the basic functionality is still there. Now, when a user clicks on the "Load" link they are presented with the search results for the term "wibble".

<!DOCTYPE HTML>
<html> 
<head> 
	<title>Loader</title> 
	<style type="text/css">
        div#container {
            width:500px;
            height:500px;
            overflow:auto;
        }
    </style> 
	<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.5.0/jquery.min.js"></script> 
	<script type="text/javascript">
var externalpagepart = '#res';
var loadinggif = '/loading.gif';

$(document).ready(function(){  
    // set up the click event
	$('a.loader').live('click', function() {
		var toLoad = '/searchgoogle.php ' + externalpagepart;
		$('.content').slideUp('slow', loadContent);
		$('#load').remove();
		$('#waiting').append('<div id="load"><img src="' + loadinggif + '" alt="Loading" /></div>');
		$('#load').fadeIn('normal');
		function loadContent() {
			$('.content').load(toLoad, '', function(response, status, xhr) {
                if (status == 'error') {
                    var msg = "Sorry but there was an error: ";
                    $(".content").html(msg + xhr.status + " " + xhr.statusText);
                }            
            }).slideDown('slow', hideLoader());
		}
		function hideLoader() {
			$('#load').fadeOut('normal');
		}
		return false;
	});
});
    </script>
</head>
<body>
    <p><a class="loader" href="javascript: null(0);">Load</a></p>
    <div id="container">
        <p id="waiting"></p>
        <div class="content"></div>
    </div>  
</body>
</html>

Finally, I thought it might be a good idea to integrate a input box into the page so that the user can control the search term they want to send over to Google. The first task is to do is to allow the passing of a post variable called 'string' to the Google search URL. This is wrapped in a call to urlencode() to stop any errors occurring when users type in spaces and other things. We will come onto how to send this data in the next snippet.

<?php
$url = 'http://www.google.com/search?hl=en&q=';
$postVariable = 'string';

if (isset($_POST['string'])) {
    $output = file_get_contents($url . urlencode($_POST[$postVariable]));    
    $output = preg_replace('#<script.*</script>#ismU', '', $output);
    $output = preg_replace('#<style.*</style>#ismU', '', $output);    
    echo $output;
}

To pass post values through the AJAX call we need to use the second parameter in the load() function. This is a JSON encoded collection of variables that we might want to use. The property of the JSON object is the key in the $_POST array on the PHP side. To send the value "wibble" to the previous PHP code snippet we use the following:

$('.content').load(toLoad, {'string': 'wibble'}, function(response, status, xhr) {

We can now tie this all together and create a form that will allow users to search Google without actually leaving the current page. To use this just type a value into the input box and click on the link. This will trigget the action and run the load() method. This can probably be tied into a form properly, but this is enough to demonstrate how things would work.

<!DOCTYPE HTML>
<html> 
<head> 
	<title>Loader</title> 
	<style type="text/css">
        div#container {
            width:500px;
            height:500px;
            overflow:auto;
        }
    </style> 
	<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.5.0/jquery.min.js"></script> 
	<script type="text/javascript">
var externalpagepart = '#res';
var loadinggif = '/loading.gif';

$(document).ready(function(){  
    // set up the click event
	$('a.loader').live('click', function() {
		var toLoad = '/searchgoogle.php ' + externalpagepart;
		$('.content').slideUp('slow', loadContent);
		$('#load').remove();
		$('#waiting').append('<div id="load"><img src="' + loadinggif + '" alt="Loading" /></div>');
		$('#load').fadeIn('normal');
		function loadContent() {
            var searchterm = $('#searchterm').val();
			$('.content').load(toLoad, {'string': searchterm}, function(response, status, xhr) {
                if (status == 'error') {
                    var msg = "Sorry but there was an error: ";
                    $(".content").html(msg + xhr.status + " " + xhr.statusText);
                }            
            }).slideDown('slow', hideLoader());
		}
		function hideLoader() {
			$('#load').fadeOut('normal');
		}
		return false;
	});
});
    </script>
</head>
<body>
    <input type="text" name="searchterm" id="searchterm" value="wibble" />
    <p><a class="loader" href="javascript: null(0);">Load</a></p>
    <div id="container">
        <p id="waiting"></p>
        <div class="content"></div>
    </div>  
</body>
</html>

One final thing that might be a good idea to do is strip out any style and script tags within the content of the page, this can be done through two calls to preg_replace(). This is probably a prudent thing to do anyway as you can end up with unwanted CSS and potentially dangerous JavaScript appearing on your site.

$url = 'http://www.google.com/search?hl=en&q=';
$postVariable = 'string';

if (isset($_POST['string'])) {
    $output = file_get_contents($url . urlencode($_POST[$postVariable]));    
    $output = preg_replace('#<script.*</script>#ismU', '', $output);
    $output = preg_replace('#<style.*</style>#ismU', '', $output);    
    echo $output;
}

This was al quite easy to set up and shows the power that a simple load() call can have, especially within a CMS application. Feel free to use these examples on your own sites but drop me a message to let me know as I would quite like to see other people's implementation of this method.

Comments

Here you send variables to google as GET variables. What if I wanted to send as POST Variables.
Permalink
As much as I want to get rid of the bloat of JQuery, the concept of maintaining more SLoC within the project is actually a worse off decision IMO.
Permalink
This jQuery Load tutorial is very well explained. I just have one question which is - how to use jQuery Load to make cross domain calls. Please help thank you.
Permalink
Thank you so much, I believe this has me on the verge of solving a 2 week long issue! I just have one more feature different than your example, and that would be a submit form and button. Is there a way to get this script to fire on submit? My current form is setup as:
id="test">
Thank you for any assistance you can provide!
Permalink

Thanks for fantastic information I was looking for this info for my mission.

Permalink

Add new comment

The content of this field is kept private and will not be shown publicly.
CAPTCHA
4 + 3 =
Solve this simple math problem and enter the result. E.g. for 1+3, enter 4.
This question is for testing whether or not you are a human visitor and to prevent automated spam submissions.