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() funciton. The first parameter of the function is the location of the resource, but it is also possible to add a CSS identifyer 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 conent, 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 occuring 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 demonstate 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.

Share:

  • Add news feed
  • Bookmark this on Delicious

Comments

Ajax not working in some cases

Hello. Thanks for the post, but I have a problem with the ajax feature with jquery.

It doesn't work in my website if it haven't the 'www.' before the name.

Example. www.mysite.com -> it works fine the ajax

mysite.com -> it doesn't work the ajax.

Does somebody know why??

Thanks!!

 

<a href="http://www.letter-example.com">Letter samples
</a>

philipnorton42's picture

Yes, the problem is because

Yes, the problem is because you are trying to violate the JavaScript same origin policy, meaning that you can't run JavaScript between one domain (or subdomain) and another. This table sums up things quite nicely.

Compared URL Outcome Reason
http://www.example.com/dir/page.html Success Same protocol and host
http://www.example.com/dir2/other.html Success Same protocol and host
http://www.example.com:81/dir/other.html Failure Same protocol and host but different port
https://www.example.com/dir/other.html Failure Different protocol
http://en.example.com/dir/other.html Failure Different host
http://example.com/dir/other.html Failure Different host (exact match required)
http://v2.www.example.com/dir/other.html Failure Different host (exact match required)

Thanks

Thank you for the explanation!

I have done some changes in my htaccess file, to redirect when the users don't put the 'www'

 

Thank you again.

Letter samples

Removing Navigation from a Page

Good article, I was hoping to use this to replace an iFrame. The page in question uses an iFrame to load a page from another website, however I only need the main content of the page loaded and not the top navigation bar. 

Will the jQuery load() function allow me to do this?

Thanks,

 

John

 

Can I use this method to

Can I use this method to strip the navigation form a page I'm loading using?

philipnorton42's picture

Thanks John! What your asking

Thanks John! What your asking should be possible, as long as the content is contains within a selectable alea.

uestion Jquery simple navigation to display content

Do you just have a demonstratin using  simple navigation links that display different content (paragraphs) on one page, no tabs, no php, just using Jquery (links only)?

Finally

Finally something that works. I think I've googled all the net these days and haven't found a script to load an external page in a div on the same page - yours does the trick.

Thank you very much!

Can this load mixed formats like an IFRAME?

Hi thanks for this great article. Very very nice. One thing - I'm currently loading some aspx code into an IFRAME on a joomla (php) site - the site and webapp are on the same domain.

CMS: http://mydomain.com/index.php
IFRAME on front page: http://mydomain.com/webapp/default.aspx

Would the above approach handle this? Or should I walk away now? :)

Thanks in advance.

philipnorton42's picture

Theoretically, it should work

Theoretically, it should work as you state. An iframe will allow you to load content from virtually any resource. If your aspx code is generating HTML then it will get shown in your iframe.

The only point I would like to raise is that the main point of this article was to load content onto a page without an iframe ;). However, the code above should work in the same way. I think...

Can I implement same functionality Without a server

Hi, This example what you explained is using AJAX in a Server. But I want to do the same functionality without using Server and Iframes.

Is it Possible? If yes, How ?

philipnorton42's picture

Hi Naveen. This technique

Hi Naveen. This technique will work with any server side technology as it's a client side script that does all of the work really. You can replace this JavaScript calls with iframes, but the whole point of the article was to not use them.

Will this load taged blogger content??

I am looking for a way to show taged content from a blog. The idea is to let the client update his blog. Then on the web page the viewer clicks on the link "surfboards for sale" and each post on the blog that is taged "surfboard" shows up. . . . . Or am I compleatly off track here?

philipnorton42's picture

Yes. I will work as long as

Yes. I will work as long as you can call the correct URL and bring through the posts that way. I have no idea how blogger works though.

How to get the body of the response

I'm writing a crawler, and I need to load web pages into a temporary div element, using jQuery.load() method. However, using such patterns as 'url-of-the-page body' won't get the body section of the result. I think, jQuery only can embed permissable elements in parent elements. In other words, you can't load an entire HTML document, into a div element.

How to replace an iframe in WP with Ajax?

Hi and thank you for the great information!

I was hoping to use this to replace an iFrame that I am using in a wordpress page also. The iframe is very slow and from all of my research I didn't think that you could do this. But I believe that it's what I need. I would love to able to add a few changes to the CSS of the ajaxed page also! 

Would someone please show me an example of how to load my external page into WP without having to use the iframe? I am not a JS developer like most of you but I do love my CSS. Any information would be greatly appreciated!

Thanks again,

Brent

Load html into div depending on drop down selection

Hi,

I am new to html and am trying to accomplish the following.

I have 12 html Pages (January through December) they are just well formed tables.

I want to load them into a div based on the user selection in a drop down. 

Can this be done?

As I said, I am new so please be gentle.

Gary 

philipnorton42's picture

You'll want to do something

You'll want to do something like the following. This is in jQuery as well, although I haven't tested it!!
$('#selectElement').change(function () {
    var elementValue= $(this).val();
    $('#test').load('/' + elementValue + '.html', '', function(response, status, xhr) {
        if (status == 'error') {
            var msg = "Sorry but there was an error: ";
            $(".content").html(msg + xhr.status + " " + xhr.statusText);
        }
    });    
});

Post new comment

The content of this field is kept private and will not be shown publicly.
  • Allowed HTML tags: <a> <em> <strong> <cite> <code> <ul> <ol> <li> <dl> <dt> <dd> <h2> <h3> <h4> <h5> <h6> <pre> <span> <p> <br />
  • Syntax highlight code surrounded by the {syntaxhighlighter SPEC}...{/syntaxhighlighter} tags, where SPEC is a Syntaxhighlighter options string or "class="OPTIONS" title="the title".

More information about formatting options

By submitting this form, you accept the Mollom privacy policy.