Edit 25.07.2018: As Pawnesh Kumar said in the answer, this seems to be a browser issue. If I hit the button multiple times in Firefox the below script will only
Note: I'm no expert, so I might be wrong. This is just my opinion.
To me, this seems like a browser quirk. It seems like Firefox intentionally ignores all the extra requests.
Chrome
In case of Chrome, if you click on the add button multiple times, multiple requests are sent to the server. Initially, all the extra requests are canceled (you can learn more about canceled
here) since the server is not responding. However, once the server responds (i-e, once the sleep time is up), all the requests are processed immediately. I don't know why, but the server only sleeps for the first request. The rest of the requests are processed immediately.
Edge
Edge also sends multiple requests if you click the button multiple times.
Firefox
Firefox is a little weird. It just sends one request no matter how many times you click the button. All the extra requests are ignored.
The fact, that you do not have multiply rows in database doesn't proof that. Maybe column "name" is unique in your table?
sudo cat /var/log/apache2/access.log
There you will find info of how many request you recieved.
It might be because you lock a file exclusively LOCK_EX
with flock
and then try to write to it with file_put_contents
which under the hood opens a new pointer with fopen
, and since you already locked the file exclusively it can't write to your file.
Try replacing the file_put_contents
with fwrite($fp, $current, strlen($current))
, and add an append flag to your fopen
like this fopen($file, a+)
Does this reproduce the issue of multiple writes?
UPDATE
The token exception mismatch from the video you provided happens because of the Laravel's CSRF protection.
Every form in Laravel needs to have a {{ csrf_field() }}
or you need to provide the crsf_token
in the Header for AJAX requests.
That csrf_token
in the form's hidden field has that same value stored in the Laravel's user session. When you double click submit fast on a form, the first request is sent with the first csrf_token
, when it hits Laravel the token sent in the form request and the token stored in the session are compared, if they are equal the request passes, and a new csrf_token
is generated in the session.
Since you did not reload the view the new token couldn't be rendered in the hidden form field, so by the time the second request hits we have a new csrf_token
in the session and the old one in the second form request and thus the exception is thrown.
UPDATE 2
As I said it was the flock
, try this code and the multiple submit issue will work
<?php
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
$file = 'file.txt';
$fp = fopen($file, 'a+');
if (flock($fp, LOCK_EX)) {
fwrite($fp, "+", 1);
flock($fp, LOCK_UN);
}
sleep(2);
}
?>
<!DOCTYPE html>
<html lang="en">
<head>
</head>
<body>
<form action="/" method="POST">
<button type="submit">Submit</button>
</form>
</body>
</html>
It is a browser thing.
I believe you are talking about the situation when a user clicks multiple times on the button. While in the background the page start reloading.
When we hit the submit button browser send the request to server. Until the response receive some browser show the old(expired) page while some simple clean the view.
In Firefox, it won't fire any event in spite of clicking many times. Wherein Chrome it submit the request to the server every time user click.
So, the bottom line it is the way the browser handles things. Your logs also showing you were using Firefox so that the case.