How to implement a time wait before html form resubmission? - mysql

I have an html form which inserts data into a database. I just built it.. it's very basic, as I'm just doing this to learn. In doing this, I see that I can hit the back browser button and post again.. and again.. and again.. and it keeps writing to the db.
I've seen sites where I try to resubmit info and it tells me I must wait 60 seconds (or whatever). Is this the preferred method to solve this problem? If so, how does one go about implementing it?
Or maybe you would handle it a different way?

When you insert a row, store the submission time in the table, or in the user's session.
Whenever you process the form, compare that time to the current time. If it's within 60 seconds, display an error instead of inserting a row.

There are two methods :
i) Simple client side javascript:
Store the time of last event in a javascript variable,
when the user does the event again , send an alert message about timing.
( This method can be fooled though by users knowing javascript )
ii) Store the time of last event in your database at backend when the form post is done. When the same form post is done again, check for the time, if it is allowed, do the processing, else reply with a message about the timing.

Related

Avoiding Envelope charges on duplicate document if a timeout was reached.

When I create an embedded document for signing, if the document times out after the 5 minutes allowed, how should I handle this? Just resend and basically create a new one? I've done this and it seems to duplicate envelopes... Is there a way to just renew the timeout, and re-direct the user to the same envelope? I've found similar posts but cant seem to find the exact answer to this... the goal of course avoiding a second envelope charge because they took longer than 5 minutes to sign the document. In creating a new envelope I'm sending the exact same document id, user etc.. but still seems to duplicate it on the back end.
The "short lived URL" that you generate from the API does expire, and it is only good for a single use. If you need another URL due to timeout or 'finish later', you can use the API to request another URL. You do not need to create another Envelope.
https://www.docusign.com/p/RESTAPIGuide/RESTAPIGuide.htm#Basic Scenarios/Embedded Signing.htm?Highlight=embedded

AngularJS form wizard save progress

I have a service in AngularJS that generates all the steps needed, the current state of each step (done, current, show, etc) and an associated directive that actually implements the service and displays the data of the service. But, there are 2 steps that are divided in 4 and 3 steps each:
Step one
Discounts
Activities
Duration
Payment Length
Step two
Identification
Personal data
Payment
How can I "save" the state of my form in case the person leaves the site and comes back later? Is it safe to use localStorage? I'm no providing support for IE6 or 7. I thought of using cookies, but that can end up being weak (or not)
Either local storage or cookies should be fine. I doubt this will be an issue, but keep in mind that both have a size limit. Also, it goes without saying that the form state will only be restored if the user returns on the same browser, and without having deleted cookies / local storage.
Another option could be to save the information server side. If the user is signed in, you can make periodic AJAX calls with the data and store the state on the server. When the user finishes all steps, you can make an AJAX call telling the server to delete any saved data it might have. This allows you to restore state even if the user returns on a different browser, as long as he is signed in.
Regardless of what direction you go with this, you can use jQuery's serialize method to serialize the form into a string and save it using your choice of storage.

PHP avoid browser reposting $_POST on page refresh?

I wonder what are the techniques i can use to avoid users to post form twice when they refresh page and chose submit again?
e.g. i have form inside regiter.php and process it as well inside register.php.
1st i could process in another file e.g. register_process.php and redirect to register.php, but then i have to create about 20 new pages and relocate a lot of code, i dont want that option.
2nd i could play with headers i dont remember exact trick but had some bad experience with that - users seen old data on page after refreshing it...
3rd i could just redirect upon success to some dummy.php and from dummy.php jump back to register.php then even if they refresh page browser would not re-post, however it does not protect against them using back button and choosing re-post, i know i could expire page, but i find that annoying experience for me and probably other users to see page expired error.
4th use some unique "access key" for each form once page loaded that will post with form and once used cannot be reused, however i kind of struggle with logics of that feature. how do know key was used without storing it in MySQL DB, i think time based accesis not great either because some users can take long between page open and form submit.
I need more suggestions how to avoid users reposing form again.
Try this:
<?php
session_start();
if( strcasecmp($_SERVER['REQUEST_METHOD'],"POST") === 0) {
$_SESSION['postdata'] = $_POST;
header("Location: ".$_SERVER['PHP_SELF']."?".$_SERVER['QUERY_STRING']);
exit;
}
if( isset($_SESSION['postdata'])) {
$_POST = $_SESSION['postdata'];
unset($_SESSION['postdata']);
}
This will basically save the POST data and cause the browser to re-request as a GET request.
5th. Use AJAX or jQuery and when the form is clicked on the page submit that data in the background. Output a response to the screen. Mark that form as submitted, or save to a session, and when they refresh they will not be able to submit the form again.
In my opinion it is the best way to do it anyway. I had a scoreboard with 20 or more forms it is worked really well to send the data without refreshing. You can return a response and make the page look very professional. Using jQuery you can also use some great form validation to make sure that they are submitting the fields that are required.
I think that the best solution would be something like this:
* create a md5 or base64 of posted data
* compare this hash with a session variable (let's call it $_SESSION['repost'])
* if hashes match, skip whatever this save should do and output a warning
* if hashes do not match, or hash is not present
* assign session variable with current hash
* do whatever save should do
When you consider the first option, I don't know about the design (programming design ^^) of your website, but you should only need 1 page. Let's says you call redirect.php with all the parameters, you should call your controller and your controller should know regardless of the parameters what to do with them.
It is a good habit to be able to do some abstraction and good design when programming, it help alot in those situation.
Other way is store the last post in the session variable, and check if is equal, like this:
<?php
... program ...
if ($_SESSION['PREPOST'] == $_POST) {
// DO SOMETHING
}
... program ...
$_SESSION['PREPOST'] = $_POST;
?>

Stream Position Returned By Box API Cannot Be Used To Track Events

Thanks for your reply for my question: Is this a bug of Box API v2 when getting events
This is a new problem related to this. The problem is that I cannot reliably use the next_stream_position I got from previous calls to track events.
Given this scenario:
Given the following two GET HTTP queries:
1. GET https://api.box.com/2.0/events?stream_position=1336039062458
This one returns the JSON file which contains one file entry of myfile.pdf and the next stream position = 1336039062934
2. GET https://api.box.com/2.0/events?stream_position=1336039062934
This call uses the stream position I got from the first call. However, it returns the JSON contains the exactly same file entry of myfile.pdf with the first call.
I think if the first call gives a stream position, it should be used as a mark for that exact time (say: TIme A). If I use that stream position in subsequent queries, no events before "Time A" should be returned.
Is this a bug? Or did I use the API in the wrong way?
Many thanks.
Box’s /events endpoint is focused on delivering to you a highly reliable list of all the events relevant to your Box account. Events are registered against a time-sequenced list we call the stream_position. When you hit the /events API and pass in a stream_position we respond to you with the events that happened slightly before that stream position, up to the current stream_position, or the chunk_size, whichever is lesser. Due to timing lag and our preference to make sure you don’t miss some event, you may receive duplicate events when you call the /events API. You may also receive events that look like they are ‘before’ events that you’ve already received. Our philosophy is that it is better for you to know what has happened, than to be in the dark and miss something important.
Box events currently give you a window roughly 5 seconds into the past, so that you don't miss some event.
We have considered just delaying the events we send you by about 5 seconds and de-duplicating the events on our side, but at this point we've turned the dial more towards real-time. Let us know if you'd prefer a fully de-duped stream, that was slower.
For now, (in beta) if you write your client to check for duplicate events, and discard them, that will be best. We are about to add an event_id to the payload so you can de-duplicate on that. Until then, you'll have to look at a bunch of fields, depending on the event type... It's probably more challenging that it is worth.
In order to help you be able to figure out if an event is a duplicate, we have now added to each event an event_id that will be unique. It is our intention that the event_id will allow you to de-duplicate the responses you receive from subsequent GET /events calls.
You can see this reflected in the updated documentation here, including example payloads.

Has form post behavior changed in modern browsers? (or How are double clicks handled by the browser)

Background: We are in the process of writing a registration/payment page, and our philosophy was to code all validation and error checking on the server side first, and then add client side validation as a second step (un-obstructive jQuery).
We wanted to disable double clicks server side, so we wrote some locking, thread-safe code to handle simultaneous posts/race conditions. When we tried to test this, we realized that we could not cause a simultaneous post or race condition to occur.
I thought that (in older browsers anyway) double clicking a submit button worked as follows:
User double clicks submit button.
Browser sends a post on the first click
On the second click, browser cancels/ignores initial post, and initiates a second post (before the first post has returned with a response).
Browser waits for second post to return, ignoring initial post response.
I thought that from the server side it looked like this: Server gets two simultaneous post requests, executes and responds to them both (unaware that no one is listening to the first response).
From our testing (FireFox 3.0, IE 8.0) this is what actually happens:
User double clicks submit button
Browser sends a post for the first click
Browser queues up second click, but waits for the response from the first click.
Response returns from first click (response is ignored?).
Browser sends a post for the second click.
So from a server side: Server receives a single post which it executes and responds to. Then, server receives a second request which it executes and responds to.
My question is, has this always worked this way (and I'm losing my mind)? Or is this a new feature in modern browsers that prevents simultaneous posts to be sent to the server?
It seems that for server side double click prevention, we don't have to worry about simultaneous posts or race conditions. Only need to worry about queued up posts.
A similar situation that you need to handle (that the javascript disable-submit-button solution doesn't cover) is the one where the user clicks Submit, the server processes the request, but while it's processing the user's internet connection goes down (perhaps they're on a train going into a tunnel).
When the train comes out of the tunnel, the user doesn't know whether their transaction succeeded or not - they pressed the button, but nothing changed on the page (or perhaps they got a "Try again" page). The natural thing for them to do is click Submit again (or the "Try again" button).
The best way to handle this situation is to include a unique transaction id in the form (in a hidden field). Generate this id randomly, and when a transaction is successfully processed, store it in the database in a list of completed transactions.
Then when you get a POST, check whether this transaction has already been seen - and if it has, skip straight to the status page. Roughly:
BEGIN TRANSACTION
SELECT *
FROM completedTransactions
WHERE userId = ... AND transactionId = ...
<if we got a result - display results of previous transaction>
<otherwise - process the request as normal>
INSERT INTO completedTransactions (userId, transactionId)
VALUES (....)
END TRANSACTION
This has the advantage that (provided you have a database that properly supports transactions - and since you're processing payments I hope you do!) you don't need to do any sort of threading or locking - things "just work".
(though be careful - some database systems can arbitrarily abort your transactions if there is a concurrency problem - but this (rare) situation is easily dealt with using a retry loop...)
As to testing double clicks from browsers: does it make any difference if you press the "stop" button between the two "submit" clicks?
this may be a stupid response, but why dont you just disable the submit button with javascript on click, so you dont have to worry about multiple clicks. i usually do this on most forms i make and it seems to solve the problem.
you already said you are using javascript so thats not the issue right?
As long as the request is in its connecting or sending stage, clicking on submit during the first submission cancels the request, starting a new one without the server 'knowing'.