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();
}
}
Related
I am in bit of a delicate situation here. In my organization we design stock management systems and it is a web application based on JSP pages and servlets which handles them.
I have been asked to fix a specific problem. We have a JSP page with an HTML form table where there are stock details. When user enters the details manually and submit the form, stock details updated in the database and it works fine.
Problem is this : When the user press the browser's back button, user can come to the previous page where he submitted the details. And when the user submit this, data is saved once more to the database.I need to prevent this behaviour.(Something likeclear and reload the page.)
Things I did so far : clear the browser cache.Code works fine but not the expected result.
Unfortunately I cannot share the code due to company regulations. What I need is a help to prevent this behaviour or a workaround.
Thanks in advance..
You can use a javascript function with the help of a hidden attribute to reload the web page. When the user press the back button,based on the value of the hidden attribute, page will be reloaded without loading the cached page.
Your approach of clearing cache is correct. Coupled with that, you can use this approach.
<input type="hidden" id="refreshed" value="no">
<script type="text/javascript">
onload=function(){
var e=document.getElementById("refreshed");
if(e.value=="no")e.value="yes";
else{e.value="no";location.reload();}
}
</script>
One drawback of this approach is if your clients' browsers have disabled JS, this will not work.Otherwise it should work.
When the user press the browser's back button, user can come to the
previous page where he submitted the details. And when the user submit
this, data is saved once more to the database.
According to how you described it, that is based on a doGet request. Which means every time you visit that URL, it will send the request with whatever parameters were added.
As someone already mentioned, if you switch the form to a post method and switch the Servlet to a doPost, you won't have this issue anymore.
Alternatively you can circumvent this with a javascript solution. Here are some options:
You can check if the user clicked the back button, disable form if true.
Another way is by storing a cookie which you check on page load, if it exists you can disable the form.
You can use this code also
$(document).ready(function() {
function disableBack() { window.history.forward() }
window.onload = disableBack();
window.onpageshow = function(evt) { if (evt.persisted) disableBack() }
});
You must use a Post-Redirect-Get pattern: https://en.m.wikipedia.org/wiki/Post/Redirect/Get.
Actually, every use of standard HTML forms with method="post" should be implemented with that pattern. It doesn't have any use for AJAX-posted forms, which actually could be another solution but will require more work and probably some architectural changes.
I had this same problem while building a django web app, and my solution was to not allow caching of the html that contains the form. In your request handler, do not allow the browser to cache the page. This will force the browser to get the page fresh from the document.
Which, in this case, you can just verify in your request handler if the requested form has already been submitted.
My code for reference:
from django.views.decorators.cache import never_cache
#never_cache
def GetForm(request, pk):
# Logic #
if (IsFormCompleted(pk)):
# Handle request #
Here is a solution.
give a random id in a hidden field on the form. Then on the server side, if the user resubmit, check if the random id already on the database. If so, redirect user.
I have a website and when a user follows an internal link I would like to pass some extra information to a new page, so JavaScript on the destination page could do some useful highlighting.
There is an option to pass that information via the link parameters (GET), but it will generate lots of virtually duplicate pages and break pretty URLs concept. Another way is to make a webapp using AJAX, but it will also bound content to a single URL.
How can I transparently pass some information to the new page during navigation w/o messing with site's URL structure?
You could store the data in local storage or session storage, and retrieve it again on the destination page.
So you have a few options.
Form Submission
First option post a form with the data. Add a hidden form, on the anchor click capture the click event, set the hidden fields with the values you want to send to the next page, and submit the form. On the next page, read the post parameters in the backend and update the page.
Local Storage
On click of the anchor, set localStorage to the values you want to appear on the next page. When the next page loads, read the localStorage values and update the page. Note: The server will not have access to the values
Ajax with pushState
Use Ajax to submit the form. When the Ajax call returns, use window.history.pushState to update the url with whatever url you want to be displayed to the user.
One of the options not mentioned is to create a dirty URL:
/destination/param1/value1/...
then strip additional parameters at server-side and redirect:
/destination
keeping additional values stored at server-side (e.g. via sessions). I still prefer using sessionStorage in a real application, but it worth mentioning anyway.
What do you mean it will "bind content to a single url"? AJAX request is the first thing that comes to my mind as the solution to this problem. You dont have to use the url of the page to make the ajax request, you can build the url inside your javascript based on whatever conditions exist in your application.
Besides AJAX and passing parameters in the URL, the only other thing I can think of is to use Cookies. That of course runs into problems if the user has cookies disabled. I think an Ajax call to your server is the most robust way of handling the problem.
Say, I have a simple form on my website having three fields : name, password and email.
I have to get these information from the users, and keep in my database.
Then redirect to another website and send all these information using post.
I also have to know whether the user was successfully redirected to that site(HTTP STATUS 200).
Here's how I'm doing it:
For Point 1, I'm simply submitting the form.
After the data has been successfully saved in my database, I'm rendering the following form with hidden fields. This gets submitted and user gets redirected to anotherwebsite.com
<form id="form_id" action="https://www.anotherwebsite.com/form" method="POST">
<input type ="hidden" name ="name" value ="$name">
<input type ="hidden" name ="password" value ="$password">
<input type ="hidden" name ="email" value ="$email">
</form>
<script> document.getElementById('form_id').submit(); </script>
Problems:
I don't think my strategy to achieve point 1 and 2 is correct. I need a better solution. Submitting the form, then rendering a page with hidden fields and submitting it again to redirect to another site just doesn't feel right.
I have no clue to achieve the 3rd point.
Based on your question you might try this approach:
create a form with name, password, email fields in a file ( HTML ).
Submit the form to server.
On the server side get the data (including the form attribute in a variable) and save it to database.
then redirect to the given website ( using the variable you've stored in step 3 ).
You can easily know the status ( 202 or any error) using any of server side scripting language.
If you are sending the user to another website, the only way to know that the user was successfully redirected is for that website to notify you in some manner. Once the user leaves your page (and that's what a redirect is - it tells the browser "leave this URI and go to this URI instead"), the scripts on that page stop running, so they can't collect any further information.
If you just need to know that the information was submitted successfully, your script could POST the data in the background, wait for a 200 response, then redirect after the information has been submitted. But that may not meet your requirements, since you still won't know if the redirect succeeded.
Another possibility which does allow you to know whether the page on the other site loaded correctly would be to open it in a new browser window/tab instead of redirecting. This is the only way to keep your page active (and, thus, your scripts able to run) while loading another page. However, it introduces other issues, like what to do with the original page. (Leave it open in the background (likely to confuse the user) or close itself after seeing that the new URI has loaded (could cause undesirable visual artifacts as one window/tab opens and then the original one closes; destroys browser history)?)
If at all possible, having the final destination site notify you when the transaction completes is almost certainly the best way to go.
To achieve point 3 you need to use cookies if you are actually trying to implement a login-cum-membersarea system. Othewise, you simple need a redirect inside a condition statement.
my $cgi = CGI->new;
if (condition) { print $cgi->redirect('https://www.examplesite.com/file.html') }
for a general way of doing point 1-2, you can look at the tutorial here:
http://practicalperl5.blogspot.com/
I'm building a contact form for my website and I would like users to enter their information, click submit, have the information process with php and to just have a message display on the bottom of the form. Originally, I was redirecting to another page and the form was working properly, but now I just want to append a small message and can't get it to work.
This is what I have currently in my contactengine.php file for it to process all the variables and send the email.
if ($success){
THIS IS WHAT I DID BEFORE THAT WORKED BUT HAS TO REDIRECT
// print "<meta http-equiv=\"refresh\" content=\"0;URL=index_thanks.html\">"; //
//BELOW IS WHAT I WANT TO OCCUR
<script type="text/javascript">
$("#contact-area").append("Thanks for your message!")
</script>
}
You don't need JavaScript for this. JavaScript is great, but it should only be used where necessary, since it can add some brittleness to the user experience.
Here's a possible design approach:
Set up a POST form
Process the form, set a session variable to thank the user, and redirect to the form again. This switches the browser from POST to GET mode†, and is usually as simple as this:
header('Location: http://yourdomain.com/form.php');
exit();
Render the form as usual. If a session variable is set to thank the user, render the thank you message, and unset the session variable‡
I wouldn't use a <meta /> refresh here - it needs to load more data to work, and is more fiddly to implement.
† The POST-redirect approach is a common design pattern in web development. There are plenty of resources about this on the web, if you are unfamiliar with it. It fixes problems associated with rendering web content inside a POST method, particularly in relation to page refreshing and using the back/forward buttons.
‡ These temporary session variables are sometimes known as flash variables. They exist from one HTTP operation to the next, and are erased at the end of the second operation.
You cannot put JavaScript inside of your PHP code. However, I will give you an explanation of what you need to do.
On the client side, bind an event for the click, then
$('form button').click(function() {
$.post('file.php', {'object': 'property'}, function(success) {
if(success) {
$("#contact-area").append("Thanks for your message!")
}
});
});
On the server side, you will process this:
//file.php
$sentByAJAX = $_POST['object'];
return true;
I'm trying to request a page and click a button on it without opening a window so I'm thinking post could work. Here is my code:
<!DOCTYPE html>
<html>
<head>
<title>test</title>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"</script>
<script>
$(document).ready(function() {
$.post(
"http://m.roblox.com/Catalog/VerifyPurchase?assetid=161075864&type=tickets&expectedPrice=1",
$("ui-block-a").submit();
);
alert("work");
});
</script>
</head>
<body>
</body>
</html>
If I'm understanding post correctly, the first argument is the url to which it requests from and the second argument is the one where you can send data. I'm trying to send a request to click the "buy" button on the page if you follow the link. Can anyone help?
A post request sends data to a given URL. What the server does with that data from that point is entirely up to the server. It is very unlikely that the web page you are trying to simulate a button press on allows that behavior. If that was possible in general, it would leave users open to some very large security vulnerabilities. For example, a site could simulate donating money via PayPal without the user ever knowing.
In this particular case, the button appears to submit a form. In that case, you could always attempt to send the request directly to the page that the form submits to, which would simulate submitting the form. However form submissions are generally protected against stuff like this, because again, it could be used to act on behalf of the user.
Basically, the best option for something like this is to provide the user with instructions detailing what they need to do, and then open the page for them.
Assuming there is no other issues like CORS you can do the post like you are trying to do, but the following is invalid.
$.post( "http://m.roblox.com/Catalog/VerifyPurchase?assetid=161075864&type=tickets&expectedPrice=1", $("ui-block-a").submit();
You are doing a POST which required the data being send to the server to be in the request body and not the URL string.
When you post to a page you are actually posting directly to the server and not a page and in this case unless the $("ui-block-a").submit(); is returning data for the page you are posting to, it is not needed.
The following would be closer to what you are looking for with that post
$.post( "http://m.roblox.com/Catalog/VerifyPurchase", { assetid: "161075864", type: "2pticketsm", expectedPrice: "1" } );
If it was successful you should see a allow-orgins error in your developer / inspector console.
$.post() is an abbreviated form of $.ajax(), with POST pre-selected as type. There are also $.get() (with GET pre-selected as type), and $.load() (with the returned data immediately injected into the specified element). But $.ajax() is the grand-daddy of them all.
AJAX is a method of exchanging data with a processor file on a server, without leaving / refreshing the page you are on. That is, with AJAX (or $.post), you can send information to a processing page on the server -- such as: my_processor.php -- the processing page can do something with the data (for example, use the data to query a database), and then echo out data, which is returned to the originating page. The received data can then be injected into a DIV on the original page, or something of the sort.
An ajax routine is usually triggered by some event on the originating page (the user presses a button, or selects a value in a drop-down, or some such). Javascript (or jQuery) code detects the event, and the AJAX code is usually actioned in the javascript event.
Here are some simple examples of what has been described.