How to do "meta refresh", but only if the page exists - javascript

I have a simple SPA used by our team, using angular1. It gets most of its data from REST calls, but I also have a "meta refresh" tag to occasionally reload the whole page, to make sure the user gets occasional small functionality changes. There is no need to ever make this optional, it should just reload the page.
The minor annoyance with this strategy is that when the user sometimes disconnects from the network (traveling between work and home, for instance), the page reload fails, and it gets into an error state. It's easy enough to just force reload the page, but I'd like for this to be a little cleaner, such that it only reloads the page if it can reach the page.
I noticed the advice at https://davidwalsh.name/meta-refresh-javascript . That uses javascript to do the reload, but it's not conditional on the page existing.
Is there a reasonable variation of this that will simply skip the reload when it can't reach the page, and then reload again when it can?

The navigator object has a property online that you could check
if(window.navigator.online){
window.location.reload();
}
Or make an ajax head request first and if that succeeds do the refresh

For my needs, I ended up implementing a "heartbeat" method in my controller, which calls a Heartbeat service, which does a HEAD request to my REST service, and returns true if the status is 200.
I then call this from the HTML like this:
<script type="text/javascript">
window.setInterval(function() {
// Call controller method to call heartbeat service.
if (angular.element(document.body).scope().heartbeat()) {
window.location.reload();
}
}, 900000)
</script>

Related

Is it possible to get data from redirection page in AJAX?

I'm in trouble. I'm trying to do something which can appear easy but I don't manage to do it.
Here is the situation :
I have 3 different html pages :
The first one called index.html is my main page with a button to lauch a test in AJAX (I'm gonna talk about it after).
The second one corresponds to a redirection to the third page.
The third one has data.
What I wanna do is :
Click on "test" button on the first page and then start an AJAX request on the second one to reach data from the third one (with the redirection) to print it in the first.
I mean the first page calls the second one in AJAX, but the just to redirect on a specific third page. Depending on the third page which is called, data returned to the first page will change.
Do you think it's possible to find a solution to this problem in Javascript ? I hope I have been clear enough.
Thank you in advance for answer.
What you are describing doesn't really make sense. There are methods of redirection that AJAX follows (an HTTP 301 code, for example). However, what you are describing is not that sort of redirect. You are describing Javascript code that, when run, will redirect the browser elsewhere.
However, you are not loading that Javascript with the browser, you are downloading the page via AJAX. Once it is downloaded, you will have the text that represents that page, but in order to find out where it would redirect to when run, you would either have to run it and somehow capture the redirect value (not recommended), or parse it yourself (also not recommended).
There are other options that could work, depending on what you are trying to accomplish:
The server could return an HTTP redirect code when the second page is requested
The second page could instead be a text or JSON file containing a URL, which the first page could read, then request data from that URL.
If there is logic in the second page that determines where the redirect goes, it could be moved to the first page
You could have the second page employ server-side scripting (PHP, etc) to determine what data should be returned and return it directly to the first page

What is the right way to call dynamic content (currently using ajax) inside a cached page?

We have a news website where we cache a complete article page.
There are 4 areas that need to continue to be dynamic on that page:
View Counter: We add +1 to view_counts of that article when page loads.
Header: On the header of the website we check if session->id exists or not if it does we display a Welcome [Name], My Profile / Logout and if not we show Register / Login.
Comments: We display the comments made for that article.
Track User Behavior: We track every single action made by users on the site
Now the only way we could think of doing this is through AJAX calls:
$('#usercheck').load(<?php echo "'" . base_url() . "ajax/check_header'"; ?>);
And so on.
This is creating a massive load on CPU, but what would be the right/alternative way of approaching this?
Please see attached:
First of all, you do not have to use AJAX for every possible dynamic content, especially in the case of comments, you may as well load them via an iframe.
That way, you are not relying on Javascript to make the request.
It may even work for the counter.
However, you problem is not Javascript, nor the database server, based on what I can see from your graph. It seems to me you have some heavy PHP controllers, maybe you are loading a heavy framework just to have $session->id checked.
Further, what do you mean by "we track every single action"? How do you track them? Are you sending an AJAX request from every little thing or are you debouncing them with JS and only sending them one every 30 seconds or so?
My advice is that you consider the size of the PHP code you are calling, and slim it down as much as you can, even to zero if it seems feasible (by leveraging localStorage to keep track of you user session after the first login), and maybe loading the counter and the comments in alternative ways.
For example, I infer you are only checking the counter once per page load, ignoring subsequent loads by other users while the current user is reading the article, so your counter may happen to be out-of-date once i a while, depending on your traffic.
I going to explain it better: your page has n views, so when I load it, you request for n and then display n+1 to me. While I'm reading, the same page gets requested and viewed x times by other users. Your counter on the server has been surely updated to n+x, but the counter on my page still says "n views".
So, what's the point in being picky and showing n+1 to me and the not updating it, thus being off by x?
So, first of all the counter controller should be as slim as possible, and what if you loaded it within an iframe, auto updating without AJAX?
How to refresh an iframe not using javascript?
That would keep the counter up-to-date, you may render it with PHP just once per page view, and then just statically serve the resulting HTML file.

Remove POST data when using custom javascript back button

I've coded some custom navigation buttons into the project I'm working on, via javascript - they essentially copy the browser button functionality (brief wasn't initially clear on why separate buttons were required, but they asked for them):
function goBack() { window.history.back(); }
function goForward() { window.history.forward(); }
However, as the functionality is the same as the browser back button, the website asks if I want to resubmit POST data if I go back to a page with said POST data, which is undesirable. Ideally, to fit with the current site setup (all POSTs submit to the originating page, which checks for POST data and performs the relevant submissions to the database), I want to clear the POST data so there is no request to resubmit.
I'm not familiar with the Post/Redirect/Get (PRG) that people might recommend, and it doesn't seem to cover the concept of continually pressing "back"; if you submit a form, you post to a page which handles the post action, then redirects to a GET page - but the redirect is still in the history, meaning if you go back, surely you would hit the redirect page and just be sent "forward"? Plus, PRG seems mostly centred on page refreshing, which is not what I'm looking for at the moment.
The concept of PRG also seems to be due to the browser back button not allowing for additional code to control POST data, so coders have to make the best of what they can access.
With my relative freedom of having a custom back button which could allow for manipulation of POST/session/cookie data, I'd consider there should be some method of calling a global session variable or cookie on back button press, which then gets picked up on the previous page load to unset the POST data and the global session variable/cookie, but my attempts to implement something like this have not succeeded - they've been simple single-line setcookie('back', true) or set($_SESSION['back']=true) PHP snippets within goBack(), with PHP earlier in the page:
<?php if (isset([either set cookie or set session variable]) {
unset([either set cookie or set session variable]); // also tried changing 'true' to 'false' here
unset($_POST);
}?>
Is this kind of behaviour possible and I'm just looking at this from the wrong angle, or is the only way to do a successful back action while suppressing POST to re-engineer the site to use PRG, which will be comparatively significant legwork? Is there some other point in a page load/POST submit that would allow for clearing the POST data, to allow for the back button functionality I'm looking for?
EDIT
I, as an example, navigate to site.com/stuff/edit/[an ID], to edit an item of stuff. The first time I visit, there is no POST data, so the PHP check of isset($_POST) returns false and the page is simply rendered with a form which is populated by a GET.
I amend in the form and press submit. The submit sends the POST data to the target page; this is STILL site.com/stuff/edit/[an ID]! However, because there is now POST data, the PHP picks this up, validates it on the page (you'll see why later) and performs backend model and controller functions to update the item to the database serving the site.
Depending on whether the update was successful, the page then renders the form again, with the information which is retrieved from a GET, which pulls the information from the server (amended or otherwise) and either a success or fail message.
If I want to add a new item, I navigate to site.com/stuff/new; this navigates to the same page as site.com/stuff/edit, but PHP code determines the masking URL and renders different aspects of the code to look like a different page with a different POST action - it also notes there is no ID passed in.
I add an item, and the POST redirects back to the same page; this time, though, there is no Id from the server, meaning the code behind picks up the fact it is a new entry, and performs an insert. It then either displays a success message with a link to view/edit the new item, or a failure message with a prepopulated form to reduce retyping the new item into the form.
I hope this has helped show how this page works; its not necessarily how I would have written the site, but I've inherited the work from an ongoing situation and work with others who code in this way, so I need to be consistent or make unobtrusive changes rather than radical redesigns of in-use code.
I think this should do the job:
function goBack() {
var referrer = document.referrer;
if(referrer != '') {
window.location = referrer;
} else {
window.history.back();
}
}

How to append parameters to URL before page starts loading?

In Chrome, I'm looking to detect in a page URL is going to be on example.com's domain, and if it is, before loading, append foo=bar as a parameter and load that instead.
I've found that I can access when the Omnibar has been submitted here, but it seems like it'd load the original URL anyways, and while that's alright it's twice the bandwidth I feel is necessary. It's not a problem when it's only one page, but it's a change that needs to happen on every page in an site, so double the bandwidth definitely becomes an issue.
Currently, it works to detect if the URL is going to be example.com and is submitted, then call window.stop() and then set location.href to example.com/&?foo=bar but that doesn't seem ideal.
In short, the user goes to http://www.example.com and then the script changes it to http://www.example.com/&?foo=bar before loading the original link.
Take a look at the chrome.webRequest API, in particular the following method:
onBeforeRequest (optionally synchronous)
Fires when a request is about to occur. This event is sent before any TCP connection is made and can be used to cancel or redirect requests.
You can use
window.location.search = "foo=bar"
may be this helps.

executing a one time javascript code after authentication

After authentication, the server side code either goes to a default page or goes to the original page on which the user had clicked before authentication. In all cases, the page is rendered after a redirect (I am using django). In this case, how do you execute a one time javascript code on the rendered page? One way I can think of is to add a "parameter" that indicates to the page being rendered that the one time code should be executed. The "onload" function can then check and execute the code. Is there any other, "more elegant" way?
You can either set a cookie or add a class on the body with Django. On the client side you simply check if the cookie or the class is present. In case of the cookie it would be best to delete it with JavaScript.
I think the solution you're describing is within the acceptable range of elegance. Anyway, another approach is to use cookies:
The authentication page will set a cookie, the page you land at (after authentication) will check this cookie. If it's there it will run this 'one time' code and clear the cookie.

Categories