Rectangle 27 1

php Update whole page on Ajax request?


document.open();
document.write(responseText);
document.close();

Bottom line is: you shouldn't have to do this, but if there is nothing else you can do (like returning an url string) the code above might work.

I had a similar issue once. A full error page was returned instead of a simple HTML snippet. We eventually fixed this by changing the logic, but here is one of the solutions I found:

The reason we abandoned this is that on IE there were some problems. I didn't loose any time to investigate why, but it threw an 'Access denied' exception when attempting to write the string. I think there were some <meta> tags that confused IE, or maybe conditional comments, I'm not sure. (It worked when I used some simple pages...)

Note
Rectangle 27 1

php Update whole page on Ajax request?


$.ajax({
    type: 'POST',
    url: "/test.php",
    data: {ajax : true},
    dataType: "json",
    success: function( json) {
        if( json.redirect) {
            if( json.load_html) {   
                // If the History API is available  
                if( !(typeof history.pushState === 'undefined')) {
                    history.pushState( 
                        { url: redirect_url, title: document.title}, 
                        document.title, // Can also use json.title to set previous page title on server
                        redirect_url
                    );
                }
                // Output the HTML
                document.open();
                document.write( json.html);
                document.close();
            }
            else {
                window.location = redirect_url;
            }
        }
        else {
            $('#message').html( json.message);
        }
    },
});
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
    <script src="//ajax.googleapis.com/ajax/libs/jquery/1.7.0/jquery.min.js" type="text/javascript"></script>
    <title>Default Page</title>

    <script type="text/javascript"">        
        $( document).ready( function() {
            $('#ajax_link').click(  function() {
                var redirect_url = "/test.php";
                $.ajax({
                    type: 'POST',
                    url: "/test.php",
                    data: {ajax : true},
                    dataType: "json",
                    success: function( json) {
                        if( json.redirect) {
                            if( json.load_html) {   
                                // If the History API is available  
                                if( !(typeof history.pushState === 'undefined')) {
                                    history.pushState( 
                                        { url: redirect_url, title: document.title}, 
                                        document.title, // Can also use json.title to set previous page title on server
                                        redirect_url
                                    );
                                }
                                document.open();
                                document.write( json.html);
                                document.close();
                            }
                            else {
                                window.location = redirect_url;
                            }
                        }
                        else {
                            $('#message').html( json.message);
                        }
                    },
                });
            })
        });
    </script>
</head>

<body>
    <div id="message">The default contents of the message</div>
    <a id="ajax_link" href="#">Fire AJAX</a>

</body>
</html>
<?php
// Random messages to return
$messages = array(
    'Stack Overflow',
    'Error Message',
    'Testing'
);

// If the page was requested via AJAX
if( isset( $_POST['ajax']))
{
    $response = array(
        'redirect' => // Flag to redirect
            ( rand() % 2 == 0) ? true : false, 
        'load_html' => // Flag to load HTML or do URL redirect
            ( rand() % 2 == 0) ? true : false,
        'html' => // Returned HTML
            '<html><head><title>AJAX Loaded Title</title></head><body>It works!</body></html>',
        'title' => 'History API previous title',
        'message' => // Random message
            $messages[ (rand() % count( $messages)) ]
    );
    echo json_encode( $response);
    exit;
}
document.open();                 document.write( json.html);                 document.close();
  • A URL, which causes the browser to redirect to the URL
  • A complete HTML page, which calls the History API's history.pushState() to add the current URL to the browser's history and replaces the entire HTML on the page with the HTML returned from AJAX.
  • A message through AJAX, which updates a <div> container.

Here is the complete HTML source of my tested file. I tested it in FF4 - FF8. Note that jQuery provides the ready method to prevent the JS from executing until the DOM is loaded. I've also used Google's hosting of jQuery, so you do not need to upload a copy of jQuery to your server to test this.

My solution allows for AJAX to return the following:

Since I am using jQuery, lets start with that. The following submits an AJAX POST to the server, to the above PHP script at URL test.php. Note that it also sets the POST parameter ajax to be true, enabling the PHP script to detect that it received an AJAX request. The dataType field tells jQuery that the server's response will be in JSON, and that it should decode that JSON to a JSON object in the response callback. Finally, the success callback, which is fired when the AJAX response is successfully received, determines what to do based on the flags sent from the server.

Since the request is for an updated answer, here's my solution using HTML5's History API with jQuery. It should run easily by combining the PHP and HTML parts into one file.

This is just a sample of what the PHP script will need to return when it is invoked via AJAX. It shows how to encode flags to determine whether the AJAX call should update the container or load a new page, and how to return its result via JSON through json_encode. For completeness, I named this script test.php.

Note
Rectangle 27 1

php Update whole page on Ajax request?


$.ajax({
    type: 'POST',
    url: "/test.php",
    data: {ajax : true},
    dataType: "json",
    success: function( json) {
        if( json.redirect) {
            if( json.load_html) {   
                // If the History API is available  
                if( !(typeof history.pushState === 'undefined')) {
                    history.pushState( 
                        { url: redirect_url, title: document.title}, 
                        document.title, // Can also use json.title to set previous page title on server
                        redirect_url
                    );
                }
                // Output the HTML
                document.open();
                document.write( json.html);
                document.close();
            }
            else {
                window.location = redirect_url;
            }
        }
        else {
            $('#message').html( json.message);
        }
    },
});
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
    <script src="//ajax.googleapis.com/ajax/libs/jquery/1.7.0/jquery.min.js" type="text/javascript"></script>
    <title>Default Page</title>

    <script type="text/javascript"">        
        $( document).ready( function() {
            $('#ajax_link').click(  function() {
                var redirect_url = "/test.php";
                $.ajax({
                    type: 'POST',
                    url: "/test.php",
                    data: {ajax : true},
                    dataType: "json",
                    success: function( json) {
                        if( json.redirect) {
                            if( json.load_html) {   
                                // If the History API is available  
                                if( !(typeof history.pushState === 'undefined')) {
                                    history.pushState( 
                                        { url: redirect_url, title: document.title}, 
                                        document.title, // Can also use json.title to set previous page title on server
                                        redirect_url
                                    );
                                }
                                document.open();
                                document.write( json.html);
                                document.close();
                            }
                            else {
                                window.location = redirect_url;
                            }
                        }
                        else {
                            $('#message').html( json.message);
                        }
                    },
                });
            })
        });
    </script>
</head>

<body>
    <div id="message">The default contents of the message</div>
    <a id="ajax_link" href="#">Fire AJAX</a>

</body>
</html>
<?php
// Random messages to return
$messages = array(
    'Stack Overflow',
    'Error Message',
    'Testing'
);

// If the page was requested via AJAX
if( isset( $_POST['ajax']))
{
    $response = array(
        'redirect' => // Flag to redirect
            ( rand() % 2 == 0) ? true : false, 
        'load_html' => // Flag to load HTML or do URL redirect
            ( rand() % 2 == 0) ? true : false,
        'html' => // Returned HTML
            '<html><head><title>AJAX Loaded Title</title></head><body>It works!</body></html>',
        'title' => 'History API previous title',
        'message' => // Random message
            $messages[ (rand() % count( $messages)) ]
    );
    echo json_encode( $response);
    exit;
}
  • A URL, which causes the browser to redirect to the URL
  • A complete HTML page, which calls the History API's history.pushState() to add the current URL to the browser's history and replaces the entire HTML on the page with the HTML returned from AJAX.
  • A message through AJAX, which updates a <div> container.

Here is the complete HTML source of my tested file. I tested it in FF4 - FF8. Note that jQuery provides the ready method to prevent the JS from executing until the DOM is loaded. I've also used Google's hosting of jQuery, so you do not need to upload a copy of jQuery to your server to test this.

My solution allows for AJAX to return the following:

Since I am using jQuery, lets start with that. The following submits an AJAX POST to the server, to the above PHP script at URL test.php. Note that it also sets the POST parameter ajax to be true, enabling the PHP script to detect that it received an AJAX request. The dataType field tells jQuery that the server's response will be in JSON, and that it should decode that JSON to a JSON object in the response callback. Finally, the success callback, which is fired when the AJAX response is successfully received, determines what to do based on the flags sent from the server.

Since the request is for an updated answer, here's my solution using HTML5's History API with jQuery. It should run easily by combining the PHP and HTML parts into one file.

This is just a sample of what the PHP script will need to return when it is invoked via AJAX. It shows how to encode flags to determine whether the AJAX call should update the container or load a new page, and how to return its result via JSON through json_encode. For completeness, I named this script test.php.

Note
Rectangle 27 1

php Update whole page on Ajax request?


<a href="javascript:response">load</a>
function source2url(src) {
    // make valid javascript string from source text
    var esc1 = src
        .replace(/\\/g, '\\\\')
        .replace(/\'/g, '\\\'')
        .replace(/\x0A/g, '\\x0A')
        .replace(/\x0D/g, '\\x0D');

    // make valid url from that
    return "javascript:'" + encodeURIComponent(esc1) + "'";
}

window.location.href = source2url(response);

A similar approach is to use base64 encoding in a data URI. The Wikipedia entry explains how it works, including a javascript example. However, you'd have to base64-encode the content somehow. (Note: You can use data URIs with or without the base64 encoding. You have to see what gives you shorter URIs for your specific content.)

A variant of this is building the URL not with the variable name, but with the actual string data. Like

In case you're forced to take the way you already go, and provided the response content is not very large, you could try Javascript-URIs. Basically, an URI in the form of javascript:"string" will load a new page which that string is the source code for. So, if response already is a string, just assigning javascript:response to window.location.href should suffice. Maybe you have to do some escaping beforehand. And I don't know, how cross-browser-compatible this approach is.

Quite frankly, I think that approach is basically broken by design. You shouldn't have to make that decision at that place. For example, the ajax response could only signal that a whole new page should be loaded and the new content then be generated on a second (non-ajax) request to a new URL.

This will, of course, generate pretty large URIs. And you'll always have the Javascript-URI in the address bar.

Totally agree on the fact that the server should send only a signal about what the client should do: display provided data or load a new URL. The server could simply echo some JSON encoded string, which could be of the form: {"type":"url","content":"ULR/to/my/new/page"} or: {"type":"data","content":"Content to display somewhere in my page"} Then the client could do what's most appropriate, according to the "type" property.

Note
Rectangle 27 1

php Update whole page on Ajax request?


var new_doc = (new DOMParser).parseFromString(response, "application/xml");
document.replaceChild(document.adoptNode(new_doc.doctype), document.doctype);
document.replaceChild(document.adoptNode(new_doc.documentElement), document.documentElement);

It's really easy if the response is valid XML.

Note
Rectangle 27 1

php Update whole page on Ajax request?


<a href="javascript:response">load</a>
function source2url(src) {
    // make valid javascript string from source text
    var esc1 = src
        .replace(/\\/g, '\\\\')
        .replace(/\'/g, '\\\'')
        .replace(/\x0A/g, '\\x0A')
        .replace(/\x0D/g, '\\x0D');

    // make valid url from that
    return "javascript:'" + encodeURIComponent(esc1) + "'";
}

window.location.href = source2url(response);

A similar approach is to use base64 encoding in a data URI. The Wikipedia entry explains how it works, including a javascript example. However, you'd have to base64-encode the content somehow. (Note: You can use data URIs with or without the base64 encoding. You have to see what gives you shorter URIs for your specific content.)

A variant of this is building the URL not with the variable name, but with the actual string data. Like

In case you're forced to take the way you already go, and provided the response content is not very large, you could try Javascript-URIs. Basically, an URI in the form of javascript:"string" will load a new page which that string is the source code for. So, if response already is a string, just assigning javascript:response to window.location.href should suffice. Maybe you have to do some escaping beforehand. And I don't know, how cross-browser-compatible this approach is.

Quite frankly, I think that approach is basically broken by design. You shouldn't have to make that decision at that place. For example, the ajax response could only signal that a whole new page should be loaded and the new content then be generated on a second (non-ajax) request to a new URL.

This will, of course, generate pretty large URIs. And you'll always have the Javascript-URI in the address bar.

Totally agree on the fact that the server should send only a signal about what the client should do: display provided data or load a new URL. The server could simply echo some JSON encoded string, which could be of the form: {"type":"url","content":"ULR/to/my/new/page"} or: {"type":"data","content":"Content to display somewhere in my page"} Then the client could do what's most appropriate, according to the "type" property.

Note
Rectangle 27 1

php Update whole page on Ajax request?


$.ajax({
    type: 'POST',
    url: "/test.php",
    data: {ajax : true},
    dataType: "json",
    success: function( json) {
        if( json.redirect) {
            if( json.load_html) {   
                // If the History API is available  
                if( !(typeof history.pushState === 'undefined')) {
                    history.pushState( 
                        { url: redirect_url, title: document.title}, 
                        document.title, // Can also use json.title to set previous page title on server
                        redirect_url
                    );
                }
                // Output the HTML
                document.open();
                document.write( json.html);
                document.close();
            }
            else {
                window.location = redirect_url;
            }
        }
        else {
            $('#message').html( json.message);
        }
    },
});
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
    <script src="//ajax.googleapis.com/ajax/libs/jquery/1.7.0/jquery.min.js" type="text/javascript"></script>
    <title>Default Page</title>

    <script type="text/javascript"">        
        $( document).ready( function() {
            $('#ajax_link').click(  function() {
                var redirect_url = "/test.php";
                $.ajax({
                    type: 'POST',
                    url: "/test.php",
                    data: {ajax : true},
                    dataType: "json",
                    success: function( json) {
                        if( json.redirect) {
                            if( json.load_html) {   
                                // If the History API is available  
                                if( !(typeof history.pushState === 'undefined')) {
                                    history.pushState( 
                                        { url: redirect_url, title: document.title}, 
                                        document.title, // Can also use json.title to set previous page title on server
                                        redirect_url
                                    );
                                }
                                document.open();
                                document.write( json.html);
                                document.close();
                            }
                            else {
                                window.location = redirect_url;
                            }
                        }
                        else {
                            $('#message').html( json.message);
                        }
                    },
                });
            })
        });
    </script>
</head>

<body>
    <div id="message">The default contents of the message</div>
    <a id="ajax_link" href="#">Fire AJAX</a>

</body>
</html>
<?php
// Random messages to return
$messages = array(
    'Stack Overflow',
    'Error Message',
    'Testing'
);

// If the page was requested via AJAX
if( isset( $_POST['ajax']))
{
    $response = array(
        'redirect' => // Flag to redirect
            ( rand() % 2 == 0) ? true : false, 
        'load_html' => // Flag to load HTML or do URL redirect
            ( rand() % 2 == 0) ? true : false,
        'html' => // Returned HTML
            '<html><head><title>AJAX Loaded Title</title></head><body>It works!</body></html>',
        'title' => 'History API previous title',
        'message' => // Random message
            $messages[ (rand() % count( $messages)) ]
    );
    echo json_encode( $response);
    exit;
}
document.open();                 document.write( json.html);                 document.close();
  • A URL, which causes the browser to redirect to the URL
  • A complete HTML page, which calls the History API's history.pushState() to add the current URL to the browser's history and replaces the entire HTML on the page with the HTML returned from AJAX.
  • A message through AJAX, which updates a <div> container.

Here is the complete HTML source of my tested file. I tested it in FF4 - FF8. Note that jQuery provides the ready method to prevent the JS from executing until the DOM is loaded. I've also used Google's hosting of jQuery, so you do not need to upload a copy of jQuery to your server to test this.

My solution allows for AJAX to return the following:

Since I am using jQuery, lets start with that. The following submits an AJAX POST to the server, to the above PHP script at URL test.php. Note that it also sets the POST parameter ajax to be true, enabling the PHP script to detect that it received an AJAX request. The dataType field tells jQuery that the server's response will be in JSON, and that it should decode that JSON to a JSON object in the response callback. Finally, the success callback, which is fired when the AJAX response is successfully received, determines what to do based on the flags sent from the server.

Since the request is for an updated answer, here's my solution using HTML5's History API with jQuery. It should run easily by combining the PHP and HTML parts into one file.

This is just a sample of what the PHP script will need to return when it is invoked via AJAX. It shows how to encode flags to determine whether the AJAX call should update the container or load a new page, and how to return its result via JSON through json_encode. For completeness, I named this script test.php.

Note
Rectangle 27 1

php Update whole page on Ajax request?


document.open();
document.write(responseText);
document.close();

Bottom line is: you shouldn't have to do this, but if there is nothing else you can do (like returning an url string) the code above might work.

I had a similar issue once. A full error page was returned instead of a simple HTML snippet. We eventually fixed this by changing the logic, but here is one of the solutions I found:

The reason we abandoned this is that on IE there were some problems. I didn't loose any time to investigate why, but it threw an 'Access denied' exception when attempting to write the string. I think there were some <meta> tags that confused IE, or maybe conditional comments, I'm not sure. (It worked when I used some simple pages...)

Note
Rectangle 27 1

php Update whole page on Ajax request?


var new_doc = (new DOMParser).parseFromString(response, "application/xml");
document.replaceChild(document.adoptNode(new_doc.doctype), document.doctype);
document.replaceChild(document.adoptNode(new_doc.documentElement), document.documentElement);

It's really easy if the response is valid XML.

Note
Rectangle 27 1

php Update whole page on Ajax request?


$.ajax({
      url:'myAjax.php',
      data:{datakey:datavalue},
      dataType:"JSON",
      success: function (response) {
           if(response.message=="your message")
           {
             $('#message').html(response.content);
           }
           else
           {
             $('#page').html(response.content);   
           }
      }
     });
<body id="page">
<div id="message"></div>
Note