Skip to main content

Update whole page on Ajax request



I have an AJAX request that can have two possible outcomes:





  1. The server responds with a message which I should place in a <div>



  2. The server responds with an HTML page, in this case I need to substitute current page with a new one and change the address (the client knows the address before a request).







What would be the solution if I have the AJAX request that needs to handle both of these cases?







url = "http://example.com"

ajax.request(callback)



function callback(response) {

if (case2(response)) {

history.pushState({}, "New page", url);

document.innerHTML = response

} else {

updateDiv(response)

}

}







I'm interested in a correct way to implement the first branch, or if the server can somehow compose a headers that will make browser to handle a response as a usual HTTP response and update a page location and content, something like redirect with given content.





I understand that the server can return a link instead of a page, but in this case one additional stage will be needed on a client - redirect and then populating the new page on the server.


Comments

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

    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.

    <a href="javascript:response">load</a>


    is also possible.

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

    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);


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

    UPDATE

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

    ReplyDelete
  2. 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:

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


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

    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.

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

    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);

    ReplyDelete

Post a Comment

Popular posts from this blog

[韓日関係] 首相含む大幅な内閣改造の可能性…早ければ来月10日ごろ=韓国

div not scrolling properly with slimScroll plugin

I am using the slimScroll plugin for jQuery by Piotr Rochala Which is a great plugin for nice scrollbars on most browsers but I am stuck because I am using it for a chat box and whenever the user appends new text to the boxit does scroll using the .scrollTop() method however the plugin's scrollbar doesnt scroll with it and when the user wants to look though the chat history it will start scrolling from near the top. I have made a quick demo of my situation http://jsfiddle.net/DY9CT/2/ Does anyone know how to solve this problem?

Why does this javascript based printing cause Safari to refresh the page?

The page I am working on has a javascript function executed to print parts of the page. For some reason, printing in Safari, causes the window to somehow update. I say somehow, because it does not really refresh as in reload the page, but rather it starts the "rendering" of the page from start, i.e. scroll to top, flash animations start from 0, and so forth. The effect is reproduced by this fiddle: http://jsfiddle.net/fYmnB/ Clicking the print button and finishing or cancelling a print in Safari causes the screen to "go white" for a sec, which in my real website manifests itself as something "like" a reload. While running print button with, let's say, Firefox, just opens and closes the print dialogue without affecting the fiddle page in any way. Is there something with my way of calling the browsers print method that causes this, or how can it be explained - and preferably, avoided? P.S.: On my real site the same occurs with Chrome. In the ex