Using jQuery To Load Content Onto A Page Without An iFrame

Tuesday, February 8, 2011 - 23:20

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.

1
2
<?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.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
<!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.

1
<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.

1
                $('#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".

1
2
3
4
<?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".

1
                $('#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".

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
<!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.

1
2
3
4
5
6
7
8
9
10
<?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:

1
                        $('.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.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
<!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.

1
2
3
4
5
6
7
8
9
$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.

Category: 
philipnorton42's picture

Philip Norton

Phil is the founder and administrator of #! code and is an IT professional working in the North West of the UK.
Google+ | Twitter

Comments

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
Submitted by philipnorton42 on Mon, 02/14/2011 - 13:26

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)

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 strip the navigation form a page I'm loading using?

philipnorton42's picture
Submitted by philipnorton42 on Wed, 02/23/2011 - 09:45

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

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 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!

philipnorton42's picture
Submitted by philipnorton42 on Thu, 12/01/2011 - 12:01

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...

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
Submitted by philipnorton42 on Thu, 12/08/2011 - 10:11

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.

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
Submitted by philipnorton42 on Fri, 12/23/2011 - 11:24

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.

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.

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

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
Submitted by philipnorton42 on Wed, 02/08/2012 - 10:32

You'll want to do something like the following. This is in jQuery as well, although I haven't tested it!!
1
2
3
4
5
6
7
8
9
$('#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);
        }
    });    
});

Thank you very much for sharing. Definitely solved my problem.

Hi,

Can I use it as login from?

if yes how?

Thanks

Hi,

Thanks for this wonderful post.... congratulations....

I was trying to use this method, but i am missing the <script> code which contains the javascript from the url i am loading.

i googled and found out jquery filters that <script> code,

You are genious and must have some alternative to this , please let me know how to get that <script> code too...

Thanks in advance...

hi. i'm trying to load a file with jquery.

example: $('#list_products').load("products/list_products.php", { 'filtro': id, 'tipo' : 'search' });

in my personal computer  the products is loading correctly. in the server i see that is not passing the variables (filtro and tipo)

can you help me please.

personal computer : windows 7
server : linux 

philipnorton42's picture
Submitted by philipnorton42 on Fri, 04/20/2012 - 10:15

Thanks for the comment Jake. All of the source code for this is right here on the page the zip file wouldn't contain anything else.

Looking at your example I would say that the JavaScript appears to be fine, it is the PHP script that appears not to produce any output. Try just echoing a string and seeing if that appears before trying to do more complex things with Google.

Remember that the Google example uses a POST request and therefore requires the second script which 'calls' the PHP file with the correct POST variables set.

philipnorton42's picture
Submitted by philipnorton42 on Fri, 04/20/2012 - 10:24

Also remember that the URL "/random_number.php" is an absolute URL and so points to a file on the root of the domain. If you are having trouble getting Try chaning the PHP file location to e.g. "random_number.php" (without the first slash) to make it a relative reference.

Hi Philip,

  Its a nice article....Is ther any alternate for iframe to display iframe other website content as part of our page.

 

Thanks

 

Hi, i love the idea! I'm looking at doing a similar thing, i was a wordpress page to show results from a realestate site and i was wondering how i would do all of this. I've tried a lot to figure out what to do but can't quite get a grasp on it. My coding knowledge is pretty basic. I would really appreciate it! Thanks.

Hi Phil, the script works an absolute treat and solves my problem with using iframes. I have one minor problem, the returned results should display a UK pound symbol '£' next to a price, but show a question mark '?'. I've added a doctype and charset iso-8859-1 to my test page, but I still see the '?' in the returned results. My test page is located under the same domain as the site it's getting the results from. Any thoughts really appreciated. Thanks Anthony

philipnorton42's picture
Submitted by philipnorton42 on Tue, 05/15/2012 - 11:28

A question mark on any web content is usually an indication of improper encoding. I would try setting the charset to utf-8 to see if that solve the issue initially. I think you'll still need to encode the pound sign properly as "&pound;" and not as the unencoded "£" on the original page.

Thanks for the quick response. I'd tried UTF8, but unfortunately it didn't work. I suspected that the original encoding of the pound sign, might be the cause of the problem, which you've confirmed for me. I'm not sure there's anything I can do about it, as the page is using third party software. But I really appreciate your help and code. Many thanks.

The content is not retrieved and the div tag remains empty when jquery noconflict is enabled so as to allow other plugins to work. If I remove jquery no conflict , the other plugins work perfect and this script will not work.

Very cool, thanks for sharing. For fun I built the Google search tool loader. One problem though, links in my results list don't work. My domain's URL is getting prepended to the URL for the links in the Google search results. I.e. - a link to Microsft should be: http://www.microsoft.com/... But in my results list it is: www.mysite.com/url?q=http://www.microsoft.com...

My code is below and but it is not working
1
2
3
4
5
6
<script language='javascript'>
function loadContent()  
   {  
        $('#divUrl').load('www.google.com'); 
    } 
 </script>
Could you please help me

Excellent post.The post is written in very a good manner and it entails many useful information for me. I am happy to find your distinguished way of writing the post. Now you make it easy for me to understand and implement the concept.

I have a span in a form frmTest: Form in C# as below:

<span id="types" name="types" >New</span>

When the page loads, the span shows the value as "New" ( Type : New) I want to reload this span every 2 secs to get its value from the server as it keeps changing(diff possible values are New, Modify, Delete). I have been trying the following but no luck. Can you please help me with this?

My code:

setInterval(function(){ $('#types').load('frmTest.cs #types');  },2000);

Hi,

What I'm trying to do is a load a booking system thru an external link into an article. I used the code but still nothing happens. What I want to know is quite simple: is it possible to load an URL into my page using the above code? I don't need all the fancy loading gifs and CSS extraction options, just plain and simple loading the booking system into my page. For example, I want to load http://www.example.com into my page, how would the code look like?

Thanks in advance!

When i use load() function to load a page with Microsoft UpdatePanel control in it. The page is loaded OK.
In the page have a text box and button.
The first time i press button, it work well, but i press the button again then error happen.
The error is:
Sys.WebForms.PageRequestManagerServerErrorException: The state information is invalid for this page and might be corrupted.
philipnorton42's picture
Submitted by philipnorton42 on Mon, 10/08/2012 - 12:21

Sounds like the form you are trying to submit has a token based cross site request forgery prevention system. So when you submit the form the token is expired and the second request is prevented. You'll need to reload the entire form in order to get a new token.
I think...

Thanks for the awesome tutorial. I have one query though. I wrote a small wepage which had few javascript lines in it. I found out that the onload even is not triggered when the page is rendered via onLoad while the jQuery(document.ready) function is triggered. Is there any way to make sure that initial scripts (onload) are executed too?

philipnorton42's picture
Submitted by philipnorton42 on Fri, 10/12/2012 - 12:01

I wouldn't expect an onload event to run when it is rendered onto the page after the rest if the DOM has loaded. I haven't tested anything but I think the best way to get things working is to explicitly call a function either from within the load() function or chain it afterwards in the same way that I have done above with slideDown().

Hi, Thanks for the post !

Can you tell me how to use jQuery in the loaded content, please? Is it possible? Because for me it doesn't work yet. Is there a possibility to communicate in jQuery between container and content?

Phil

Hi,
This is really nice.. thanks a lot..
I have one doubt. can u tell me how to access the elements of webpage loaded in the div tag...

Hello,
I love your information and sharing your knowledge. i have a question that i hope you can help me with? i want to take the demo you provided up top of this page and change it to load a specific search results link from another domain and have the results only displayed in the body section of one of my domain site pages. i need their navigation and crap out. just the search results from their body pulled into my body of the page. i have pasted the exact search results link to the content i am struggling to do this with. Can you please help me with using the code example you wrote above!!!
thanks, Carrie

In this search link below.... when you go to this link... the part of the page i need is only the area in white background displayed. and is it possible once implemented on my domain that the code updates itself from the other domain on refresh, reload, or just when the user lands their again on my site?

http://www.ticketmaster.com/search?tm_link=tm_homeA_header_search&vid=98430&user_input=el+paso+county+&q=El+Paso+County+Coliseum

Add new comment