deal with undesirable behaviour when clicking the back button on my website - php

I've looked around for an answer to this problem, and I'm slowly accepting the fact that I've probably gone about things the wrong way, but here's a request for some wonderful pearl of wisdom that might help!
I'm working on a website which has a directory-style navigation bar on the left. So at first the user will only see two directories (Grammar / vocabulary - it's an English learning site) and by clicking on the directory, it will "open" to reveal its contents (other pages or directories).
The way I have this working is that each directory is a form submit button that reloads the page when clicked, but with a value in $_POST that tells the site to open or close a folder (this is done within an array in $_SESSION). It works great! The issue, though, is that if a user clicks the back button in their browser, they get the prompt asking if they wish to resubmit data, which is not something I want.
I was wondering if there was a way I can detect in php if the back button has been pressed, so that instead of reloading the page and making changes to the side bar, the side bar will remain the same and instead the user gets taken to the last page they had visited.
I'm aware that the real solution to this is probably just to rethink the side bar, and any advice on a better way to do that would be much appreciated also!
Michael

The reason you're getting the prompt is because POST is supposed to be used if the data being sent is going to modify something, so submitting a POST request using the back button might have unexpected behaviour (like duplicate data).
Replacing POST with GET should disable the prompt.
HTML
From:
<form action="page.php" method="post">
</form>
To:
<form action="page.php" method="get">
</form>
PHP
Change references from $_POST[''] to $_GET['']

DEMO: http://aseptik.net/php5/demo/deal-with-undesirable-behaviour-when-clicking-the-back-button-on-my-website
<?php
session_start();
if( $_GET['t'] == $_SESSION['token'] || $_SESSION['directory'] == $_GET['q'] || !isset($_GET['q']) ) {
echo "<h1><span>you going</span> forward</h1>";
} else {
echo "<h1><span>you going</span> backward</h1>";
echo "<p>should be <strong>{$_SESSION['directory']}</strong> directory</p>";
}
$token = uniqid();
$_SESSION['token'] = $token;
$_SESSION['directory'] = $_GET['q'];
?>
grammar
vocabulary
Back button re-submit form data ($_POST)
Prevent Back button from showing POST confirmation alert

As a general rule in web development you should only do a post when you are submitting data that you don't want to be resubmitted, or that you don't want to show up in your logs on the server. And once you do a post, you should redirect using get parameters or some other method.
If you use get parameters instead of post then you can just make the page navigation stateless and just fetch the page they ask for.
There are methods for detecting if the back button has been pressed, but they are difficult to make work consistently, and can be frustrating to the user, so it is recommended you go about it another way.

Related

Laravel's flash data available after browser back button clicked [duplicate]

So the SMEs at my current place of employment want to try and disable the back button for certain pages. We have a page where the user makes some selections and submits them to be processed. In some instances they have to enter a comment on another page.
What the users have figured out is that they don't have to enter a comment if they submit the information and go to the page with the comment and then hit the back button to return to the previous page.
I know there are several different solutions to this (and many of them are far more elegant then disabling the back button), but this is what I'm left with. Is it possible to prevent someone from going back to the previous page through altering the behavior of the back button. (like a submit -> return false sorta thing).
Due to double posting information I can't have it return to the previous page and then move to the current one. I can only have it not direct away from the current page. I Googled it, but I only saw posts saying that it will always return to the previous page. I was hoping that someone has some mad kung foo js skills that can make this possible.
I understand that everyone says this is a bad idea, and I agree, but sometimes you just have to do what you're told.
Don't do this, just don't. It's bad interface design and forces the user's browser to behave in a way that they don't expect.
I would regard any script that successfully stopped my back button from working to be a hack, and I would expect the IE team to release a security-fix for it.
The back button is part of their program interface, not your website.
In your specific case I think the best bet is to add an unload event to the page that warns the user if they haven't completed the form. The back button would be unaffected and the user would be warned of their action.
Nah, you're doomed. Even if you pop the page up in some different browser and hid the back button, there's always the Backspace key.
The problem with marketing guys and analyst types is that some of them do not understand the fundamental concept of the web being stateless. They do not understand that the page is totally, totally unaware of the browser using it and absolute control of the browser is totally outside the capability of web pages.
The best way to discourage your users to hit the back button is to make sure that your page loses all its data when they press back, e.g., the comment page is the only point where the data can be saved, and if they do press the back button they have to do everything all over again (think along the lines of pragma: nocache).
Users will complain, sure, but they are the reason that this godforsaken requirement exists, right?
I've seen this before:
window.onBack = history.forward();
It is most definitely a dirty hack and, if at all possible, I would attempt to not disable the back button. And the user can probably still get around it quite easily. And depending on caching, there is no telling if the server code will be processed or if the cached page with JavaScript will run first.
So, yeah, use at your own risk :)
I came up with a little hack that disables the back button using JavaScript. I checked it on chrome 10, firefox 3.6 and IE9:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" >
<title>Untitled Page</title>
<script type = "text/javascript" >
function changeHashOnLoad() {
window.location.href += "#";
setTimeout("changeHashAgain()", "50");
}
function changeHashAgain() {
window.location.href += "1";
}
// If you want to skip the auto-positioning at the top of browser window,you can add the below code:
window.location.hash=' ';
var storedHash = window.location.hash;
window.setInterval(function () {
if (window.location.hash != storedHash) {
window.location.hash = storedHash;
}
}, 50);
</script>
</head>
<body onload="changeHashOnLoad(); ">
Try to hit the back button!
</body>
</html>
Do you have access to the server-side source code? If so, you can put a check on the first page that redirects to the second page if the information has been submitted already (you'll need to use sessions for this, obviously). At a former job, this is how we handled multi-step applications (application as in application for acceptance).
Could you move the comment to the previous page and make it a required field there?
Disabling the back button will not work.
Because of the security isolation of javascript in the browser, you cannot change what the back button does.
Perhaps you could store something in the user's session that indicates that a comment is needed, and have any page in the app that the user tries to load redirect to the comment page?
What if the user closes their browser when he/she gets tot he comment page?
I know that you have not been given a choice here, but since what they are asking for seems to be impossible...
Perhaps you could just not consider the item as completed until the user enters comments. Thus, you would need to keep track of both in-progress items and completed items, and make that distinction in the UI, but this might be the most robust method.
Or just put the comment field on the form page?
What the users have figured out is
that they don't have to enter a
comment if they submit the information
and go to the page with the comment
and then hit the back button to return
to the previous page.
Then they are probably also smart enough to type 'no comment' into the comments field.
You can try to force people to add comments, but you will probably just end up with bad unusable software, annoyed users, and still not get comments. This is usually a good time to take a step back and reconsider what you are doing from the users' point of view.
Disabling the back button seems kind of a "brute force" approach.
Another option would be that you could jump out to a modal dialog that doesn't have command buttons, walk users through the workflow, and close the dialog when the process is complete.
You should secure your application against double submission instead of breaking user interface to hide the bug.
There simply is no reliable way to do this. You cannot guarantee that 100% of the time you can stop the user from doing this.
With that in mind, is it worth going to extremely exotic solutions to disable "most" of the time? That's for you to decide.
Good luck.
AS a simple solution: try this one. Insert an update panel and a button in there and use javascript to hide it and then press it on page load. Yes I understand that it will cause your page to post back on load and may not work if javascript is disabled but certainly will help you achieve a half decent response to the back button issue. Andy
You can prevent them from going back to the previous page. location.replace() replaces the current page's history entry with a new page, so...
page1.html: user clicks a link that goes to page2.html
page2.html: user clicks a link that calls location.replace('page3.html');
page3.html: user clicks back button and goes to page1.html
This may not fit well with doing a POST, but you could post the data to a web service via AJAX, then call location.replace()
If you are starting a new web app from scratch, or you have enough time to rework your app, you can use JavaScript and AJAX to avoid the browser's history, back, and forward functions.
Open your app in a new window, either before or immediately after login.
If you wish, use window options to hide the nav bar (with the back and forward buttons).
Use AJAX for all server requests, without ever changing the window's location URL.
Use a simple web API to get data and perform actions, and render the app using JavaScript.
There will be only one URL in the window's history.
The back and forward buttons will do nothing.
The window can be closed automatically on logging out.
No information is leaked to the browser history, which can help with security.
This technique answers the question, but it also contradicts best practice in several ways:
The back and forward buttons should behave as expected.
An app should not open new browser windows.
An app should still function without JavaScript.
Please carefully consider your requirements and your users before using this technique.
I don't see this solution :
function removeBack(){
window.location.hash="nbb";
window.location.hash="";
window.onhashchange=function(){window.location.hash="";}
}

Form Submit with Different Redirect Location than Action

Problem:I have an RSS feed. As some of you may know, RSS feeds do not always update promptly (I'm using FeedBurner) so I'd like to provide the option on my webpage to update the RSS feed. This is a simple process, and I just need to ping an address. The catch is this: I'd like to stay on the initial page, and ideally refresh it.
I've seen some "solutions" around with using hidden iframes, and javascript, Ajax, etc.. What I am wondering is if there is an elegant way to do this using php/html.
Below is a flowchart illustrating exactly how I would like the system to function.
EDIT:
Here is the simple form code which I currently have:
<form action="http://url.to.ping" method="post">
<input type="submit" value="Refresh" />
</form>
This is a standard form, performing an action on submit. I require now that the browsers destination (as seen from the user) is a different url than that in the action. It is worth noting that the action page is not in my domain, and is not part of a domain which I own or have access to.
Thanks!
What i meant was,
/contactme.php
once they've submitted and come back to the page is there any additional variables like
/contactme.php?thanks=1
basically is there anything to declare they have just submitted and come back to the original page, if so..
You could do;
<?php
if(isset($_GET['thanks']))
{
$pingServer = file_get_contents('http://www.the.server.to.ping.com/pingit.php');
unset($pingServer);
}
?>
at the bottom of the page and it'll just hit that page.
This way you are not relying on JavaScript being enabled and the user is not hopped around multiple URLs.
What I have done when I needed the landing page to be different from the processing page is add a JavaScript redirection where one would put their "thanks for filling out my form" material.
So, the code process would be:
user fills out form, clicks submit
server-side validation and processing.
if success then location.href(URL, 0); else do error case
user is redirected to new URL (your refresh page)

PHP - Browser BACK button crashes the website

I am a newbie to programming. I have a PHP website which works as follows
Index Page - Search Results - Show a Product
The site user enters search critera on Index Page and the page is POSTed to Search Results page. From there, the site user clicks on a Product href that takes him to the Product Details. This is working fine till here.
The problem occurs when the user click the browser BACK button. The Search Result page comes up totally crashed and the user has to press F5/Browser Refresh to re-submit it. Any idea/technqiue that I can use to avoid this crash?
When a browser goes back to a page that comes from POSTing some data, the browser often times needs to re-POST the data in order to get the same page back. Since that can sometimes be bad (e.g. re-POSTing an order form), many browsers require the user to force a refresh with a warning.
You can generally use a GET instead of a POST form to avoid this.
An idea would be using GET for the method of your search form instead of POST (that apparently you are using). That way, even if going back in browser history, your server could re-supply its search results.
You would need the following:
change method="post" to method="get" in your search form
change every $_POST relating to the search form data to $_GET in your search form processing php file.
Of course, it could not work for your specific usecase. That's just an idea.

How do you make the browser re-post form data when using the back button?

I guess my question is in understanding the $_POST handling.
So I have two pages that handle 2 forms. Page 1 asks for some information that will be used in page 2. When submitted the form action uses the same page then redirects to next page upon validation, but only handles the data when $_GET variable ?usersubmit=1.
<form action="<?=$_SERVER['PHP_SELF']?>?usersubmit=1" method="post" name="form1">
<input type="text" name="field1">
</form>
So say I have page called form1.php. Upon submit its sent to form1.php?usersubmit=1. The page now assigns the posted data to session variables and then redirects to form2.php via header('location:form2.php').
<?
if($_GET['usersubmit']){
if($_POST['field1']){
#if valid then assign session variable and redirect to next form
$_SESSION['field1'] = $_POST['field1'];
header("location:form2.php");
}else{
#if invalid send error message
$error = true;
}
}
?>
My problem is in when users hit the 'back' button on their browser to edit data from a previous form. The browser doesnt re-post this data it just shows them a blank form. I'd prefer not to use $_SESSION data to fill out the forms because I suspect the re-post method may be a quicker and less problematic fix.
I also tried a javascript redirect instead of a header but browsers are smart enough to not send you back to a page that wants to redirect you so it doesnt work.
any help in understanding this would be greatly appreciated.
thanks.
The only way to handle it is via a session... HTML5 allows for storing of that kind of data but to be honest I wouldnt even look into it as a possibility just yet, altough it does work.
typically the back button will use all of the same get and post variables as was used on the previous locations page load. server side header redirect will not allow you to use the back button to get to the previous page since this redirection is done on the server side.
there are two ways to redirect using javascript window.location which will put your previous location into the browser history and therefore the back button will work, and location.replace which will not put a link in your history, and therefore not allow you to use the back button to get to the previous page.
alternatively, you could just use page two to process page ones form...
Also, you should use htmlentities() in your code. It closes a security vulnerability (see http://www.html-form-guide.com/php-form/php-form-action-self.html for more details).
<form action="<?=$_SERVER['PHP_SELF']?>?usersubmit=1" method="post" name="form1">
should change to something like this below.
<form action="<?=htmlentities($_SERVER['PHP_SELF'])?>?usersubmit=1" method="post" name="form1">

Saving Form Data?

Is there a way to save the form data so that if the submit fails they don't have to retype everything? For some reason, I'm getting an error on my script with Chrome but not with FireFox. It doesn't always happen with Chrome, and it's not exactly the main problem. If they submit and then the page doesn't load, they lose everything they typed when they go back. I've thought of only one thing so far, but it doesn't seem practical. It would be to save the form data to cookies when they press submit.
Is there a better way?
It depends on what you mean by "submit fails." If you mean that there is a server error, and they have to press 'back', it's hard.
However, if you mean fails as in a they-forgot-to-put-an-email kind of fails, here is one solution:
You can grab the previous values from the $POST or wherever and stick them back into the HTML tags. For instance:
<?php
$prevCustEmail = makeItASafeString($_POST['custEmail']);
?>
<input type="text" id="custEmail" name="custEmail" value="<?php echo $prevCustEmail; ?>" />
Edit: For the server thing, the cookie hack may be the best. Here is another hack idea: You could modify your 500 server error page to have a button on it that says "go back to form", which would only show up in the event that this $_POST data was just went. The button would actually be submitting an identical form where every is type=hidden. This data would then get transferred to the previous page and stuffed in as above.
A third hack would be to load the page in an iframe, and have the success page jump out of the iframe. The server error would not do that. Then use Javascript onSubmit to detect that something has gone wrong, or just hope that the user notices nothing happened and clicks "submit" again.

Categories