Andrew Keeton
Andrew Keeton

Reputation: 23311

How do I "quietly" reload a page from a Greasemonkey script?

I want to reload a page so that it does not cause the effects of a full-page refresh, like displaying "Loading..." on the page's tab.

Here's the code I have so far. My theory was that I could overwrite the body section with a <frame>-wrapped version of the updated site, gotten via GM_xmlhttpRequest.

reloader.js

setInterval(reload, 10000);

function reload() {
    GM_xmlhttpRequest({method: 'GET',
            url: location.href,
            onload: function(responseDetails) {
                document.body.innerHTML =
                                '<frame>\n'
                                + responseDetails.responseText
                                + '</frame>\n';
            }});
}

When testing with Firebug on stackoverflow.com, I found that this script updates the body as if I had performed a full-page refresh, without the side effects. Yay! Mysteriously, the <frame> tags are nowhere to be found.

Questions

What I have right now does a good job of reloading the page, but I have two questions:

  1. How do I stay logged in after a reload? Specifically, what do I need to do to keep me logged in to Stack Overflow?
  2. Can someone explain why my script works? Why are there no <frame> tags within the body?

Updates

I've incorporated elements from Cleiton, Havenard, and Henrik's answers so far. I tried sending cookies via the header: { 'Cookie': document.cookie } entry in the data sent through GM_xmlhttpRequest. This sent some, but not all of the cookies. It turns out that if I turn on third party cookies in the Firefox then I'll get the necessary extra cookies (.ASPXAUTH, ASP.NET_SessionId, and user), but this is a bad idea.

Upvotes: 1

Views: 3314

Answers (4)

Cleiton
Cleiton

Reputation: 18113

@Andrew Keeton,

First install fiddler in your machine and see if http requests made by GM_xmlhttpRequest are being sent with all cookies. if isnt go to about:config option "network.cookie.cookieBehavior" and set it to 0, do another test. if it works. you will be in trouble because there isnt a safe way to perform this change using greasemonkey and you will have to use @Henrik tricky.

Upvotes: 3

Noon Silk
Noon Silk

Reputation: 55082

What site/sites are you trying to do this for?

Depending on what you need, if may be far easier/better to just change the timeout on the cookie they give you, you can set the expiry yourself, forever :)

Upvotes: 0

Havenard
Havenard

Reputation: 27864

document.body.innerHTML =
        responseDetails.responseText.match(/<body>([\s\S]*)<\/body>/i)[1];

Update: For <body> with properties:

document.body.innerHTML =
        responseDetails.responseText.match(/<body[^>]*>([\s\S]*)<\/body>/i)[1];

Upvotes: 10

Henrik Opel
Henrik Opel

Reputation: 19441

As for the logged in state I would expect this to be tracked via some form of session cookie. Make sure to set them explicitly in the GM_xmlhttpRequest header, as it does not do so by itself.

Not sure about the exact syntax right now, but it should be something like this:

GM_xmlhttpRequest({method: 'GET',
                url: location.href,
                headers: {'Cookie': document.cookie},
                onload: function(responseDetails) { ... 

Upvotes: 1

Related Questions