I am trying to set up a comment system, in which when the users sends the comment it is displayed on their screen as if it were already stored on the database.
My question is: what would happen if the users send comments and then navigate away
(or most specifically close the window immediately) or they lose connection after the ajax post?
On the code side I have ajax({})...
Then I have code that takes the user input from the textarea and adds it to a div.
This means that the user gets to see the comment they entered instantaneously. But I would like to be sure if the server will get the post info even if the connection was lost, window was closed or the user navigated away.
More info for the question:
A user sends a post to the server with 1mb of values, then right after one millisecond
he/she clicked on the button that made the post the browser window was closed.
Does the server receive and parse the response with ignore_user_abort(true);
inside the file; was the post info received?
Any difference if it were get instead of post for this case?
Assume website.com?myget=value
Trying to connect then closing the window immediately, on a browser window for example,
just hitting that on the address bar and then closing very right away, imagine it to
be automatically.
step 1 go to website.com?myget=value (don't wait at all for any server response, just
straight away (a millisecond or whatever it takes the script to do so) close completely
the window.
Would $_GET['myget'] be received server side at index.php of website.com?
This is a UX problem, not a technical one. What you want to do is display the new comment only after it has been stored. The workflow should go something like this:
User types message
User clicks on "submit" button
System grays out "submit" button and displays a message that reads,
"Posting..."
When System can confirm that the message has been successfully
stored, System will remove "Posting..." text and display actual new
message.
This way the user knows not to close their browser or navigate away until the request is done.
Alternatively you can you onbeforeunload to warn your users to wait before closing the browser or navigating away. Workflow being something like:
Prerequisite: You have a persistent counter somewhere (cookie, local storage, hidden field, etc). When the page loads, it starts at 0.
User types message
User clicks on "submit" button
AJAX request is sent
Counter is increased by 1
Request is complete, you get a response (whether it's successful or not - error handling is another issue), decrease the counter by 1
If at any point, the unload event is triggered, System will check the counter. If greater than 0, warn the user that their request has not been completed and that they might loose their comment (a-la-Gmail).
Will add my five cents. With ajax({}) you will ask browser to start communication with your server. It needs some time to establish connection (ping time) and send data to server. Both parts require some time to be completed. In order for PHP to start execution, browser must sent all data it has to send. No matter is it POST or GET. If user will break sending procedure (browser crashed, tab closed, computer turned off) PHP will not even be started. For instance, you can try to send some large file and see with a debugger when PHP script will be started - only after file is delivered completely (you can even close your browser before file is uploaded and see if your script is executed at all). It makes sense to start PHP execution only after all data delivered to server and ignore connections broken before data delivered. Otherwise there could be problems with data being corrupted. And nobody wants that. Plus, imagine that PHP is started before everything is delivered to server: you would never be sure that $_POST["something"] is not available because it was never entered by user or its data is not yet delivered.
There is no difference if you are using regular form submit or XMLHTTPRequest. In both cases browser need some time to establish connection with server and pass a data to it.
In most cases, whatever action you perform against the server will continue to be executed until such a point as the PHP running on the server tries to output results back to the browser. Only at this point will PHP check whether the connection still exists and do whatever is should do based on the user abort settings. So, if for example you wanted to receive the post, update a database entry, and then echo back some sort of success message, the database activity should continue so long as you have not made any output before the database is queried.
POST vs. GET makes no difference in this behavior.
Related
This is a JavaScript question, but not an AJAX question. Is there a way to cancel a post once it has been submitted and is in motion?
So the user hits the post button - all is well and form is submitted PHP is ready to catch the details.
For whatever reason there is network congestion and the server does not respond.
I want to give the user a chance to post again after a time has passed.
Is there a way to cancel the actual POST once it has been sent?
Is there a way to actually detect - on the server side - that a post was received? (In this case data is to be saved in the database)
I'm imagining the whole post procedure has a beginning and an end on the server side?
Or is there a way to know for sure that the post is going nowhere? It has failed and that's the end of it?
Is there a way to cancel the actual POST once it has been sent?
No, not from the server. Only from the client. You can chose to not respond to the request, but to cancel it "in the middle" is not possible from the server without some overly complicated acrobatics which you really shouldn't be doing.
Is there a way to actually detect - on the server side - that a post
was received?
Your code will only run once a request is received; so by default - if your code is running - request is received. You can use any of the logging mechanisms provided by PHP to log this event; or just check the web server logs.
I'm imagining the whole post procedure has a beginning and an end on
the server side?
Everything starts from the client, and it ends with the client as well. The client requests a resource. If there a no clients, your code is sitting idle twiddling its thumbs. Once the server receives a request from a client, it maps the request URL to a resource and then needs to deliver a response back to the client.
All web requests happen this exact same way. They are started from the client's side; and they all end when the client receives a response and the connection is closed. Then the whole cycle starts again for a new request.
Is there a way to know for sure that the post is going no where. It
has failed and that's the end of it?
If your code was not called; then there was an error at the server end (perhaps misconfiguration). The key thing to remember is the client will always get a response; and it is up to you to figure out what happened.
The best way to do this is to have smart logging in your application - or generally monitoring the server logs (where are requests are tracked).
If a post has gone "no where", the corresponding log entry will tell you. If the log entry does not show any errors and the action that you had expected (for example, a database record was created) hasn't happened - this means the problem was with your code.
If you have a requirement to make sure that a record was created only if a request was successful then use transactions if your database supports them.
Is there a way to detect whether a user is disconnected from internet or not? The way that stackoverflow does when you want to post a question. I couldn't think of any approach to do that. Could someone shed some light on the subject?
You can send AJAX-request to PHP script when windows is closed:
window.onbeforeunload = function(){
// Request goes here
}
Alternativly you can use websocket-technology (you can use phpDaemon) to connect with server permanently so you will know when user is disconnected from internet or your site or pereodicly (use setInterval function) ping your server.
I guess Stack Overflow uses AJAX, which is a JavaScript driven program executed on the client side inside your browser. This ajax setup is responsible for notifying the user when, for example, a new answer is posted, and giving them the opportunity to load said new answer without reloading the whole page.
And this construct has a way to detect errors in the communication with the server which it is interpreted as the user being disconnected, resulting in a warning.
However, this requires that the user is still having the browser open. There are also various other functions in JavaScript and AJAX to execute something when the user is closing the page, but neither of them are considered to always work. There are no silver bullets after all.
From the server's side, one can monitor the constant ping-pong of the user client's AJAX and execute something when this ping is fading away. Like: the user has been pinging us in every 5 second in the past two minutes, but now this ping is missing.
The main problem with this lies inside the principles of PHP and that every pages basically lives on its own. When the request is get, the page is loaded and created, but at the end of request, the current page instance is denied from existance, just like how every variable is lost which is not saved elsewhere (cookie, session, database).
Here is the scenario:
I have a page that is logging data to MYSQL. I have another page that reads that data and allows it to be viewed. When a new piece of data is logged I would like to have the first script check and see if the viewing page is open in the browser, and if so append the newest data to the end of the view. Also - could anyone point to some info giving an overview of how PHP and the browser interact? I think I have the concept of the DOM down for javascript...but as far as PHP it just appears that once the page is sent, that's it...
You're correct in that once the PHP is sent, that's it.
There is no way to send data to a PHP page once the page is loaded. There is another slightly nastier method, but the easiest way of doing this is going to be polling the page via Ajax.
So, have a script that every 20 seconds, sends a message to another PHP script that contains the timestamp of the last MySQL log you received, then get the script to return all the data that has been set by that time.
I'm unsure how new you are to JavaScript, but the easiest way of doing that is probably using JQuery's $.ajax and encoding the new MySQL records as JSON.
No this isn't possible as you describe. The viewing page will have to poll the server for changes, either by periodically reloading itself, or by javascript / AJAX.
You are right that once the page is sent by PHP it can have no further influence. In fact the PHP execution thread on the server is killed as soon as output is complete, so the thing that generated the page no longer even exists.
To expand on Dolondro's suggestion, rather than periodically polling the server for updates, you could use Server-Sent-Events (newly supported in modern browsers).
With these, you basically just send 1 ajax request to the server, and the connection is held open. Then, the server can send updates whenever it wants. When the browser receives an event, it can add the data to the screen. Even still, the connection is held open, and the server can send additional events/updates as they occur.
W3C page:
http://dev.w3.org/html5/eventsource/
Wikipedia:
http://en.wikipedia.org/wiki/Server-sent_events
More Info:
https://www.google.com/search?ix=hcb&sourceid=chrome&ie=UTF-8&q=server+sent+events
There might be some cases that your request takes long time because
of some problems with your client internet connection or your server
connection. So since the client doesn't want to wait he clicks on the Ajax
link again which sends the request to the server again which messes up
the following:
Rendering of our website in the browser because we are giving extra
load to the browser.
What if the second request processed correctly and you showed user
the page and then comes along the error message from your first
request(saying request timed out) which loads above on the correct
content and mess up with the user reading the correct content.
I want to stop the 1st Ajax response if the Ajax function is called twice. How do I do this?
so i want to stop the 1st Ajax response if the Ajax function is called
twice
What you actually want is to prevent a second request when a first request is in progress.
For example, You may have to change the Save button to Saving..., disable it (and add a little progress wheel) to give live feedback to the user. (Facebook does this)
The key is love feedback to the user. If the user is clueless on what is going on, they are going to think nothing is happening.
You might want to check why the operation is taking long
If this is a complex/time consuming operation, like, say a report generation or a file upload, a progress bar should do
If this is because of the client's internet connection, say it up front, like Gmail: Your have a slow Internet connection and this site may be slow. Better still, provide a fallback option, with less/no Ajax.
You say cause we are giving extra load to the browser: this is kind of fishy. You will not be giving extra load to the browser unless you are giving it tons of HTML to render. Use Ajax only for small updates on the browser. You may want to reload the page if you expect a large change.
How bout seeing as your using some form of JavaScript to begin with you have that link either hidden or disabled in a manor of speaking til the pages request has been followed through with. You could for example have the requested ajax wait for a second variable that would enable that link so a user could click it. But until that variable is received from the original AJAX request its disabled to the click, then if it is clicked it disables again and waits for the same variable to come back again.
Think of how some developers disable a submit button on a form so a user can't double submit there form.. same concept of notion here.
Okay so I'm running into a small problem.
Basicly my whole website runs through the AJAX system, content is loaded in the middle page, and theres a left and right menu which dont refresh.
Currently I'm trying to look for a PHP->Ajax feature that refreshes the whole website incase a certain record changes in the MYSQL table
Okay so every user has a record called "State" which indicates the state of their account, this can be changed by anyone, for example the account gets shot and killed by someone. How do I make it so it checks what state you have and if it changes from the "standart" state that it performs a full page refresh.
I tried to find an answer for this everywhere but haven't been able to figure something out.
-----Edit-----
Okay so I'll also notify, I kind of know how to perform a full page refresh, and I know how to retrieve data from the mysql database, this isn't the problem.
I have a table with all the users accounts in it, one of the records for every user is called "State" everybodies state will be 1 which means alive. when its 0 it means its a dead account.
On a part of my website theres an auto refresh with always fetches data from the database every 5 seconds, to check if your online if you have money etc. it also checks what state you have.
the only thing I want to do, is that when it sees your state is 0, it performs a full page refresh, considering state 0 means death, you should be seeing a deathscreen, I want it to perform a full page refresh cause the menu's have to dissapear. and it has to redirect you to the deathpage.
You need long pooling / comet - basically you keep open connection between the client and the server, and when the state is changed, the server sends the response to the client.
Basically, you'll open a long pooling connection, sending the userid.
The server script receives the userid, and starts monitoring for changes for that user. If such change is detected, send the response.
If performance is concern, you can use Tornado web server. What's nice about it, is that you can post from another application to the web server, and it can detect which client is affected by the change and send response to that client.