Pushing updates to a webpage using server-sent events - javascript

I would like to post data to my PHP page and then have it update the HTML page. I followed this example of using server-sent events to push updates to a webpage.
Here is what I have right now:
output.html:
<!DOCTYPE html>
<html>
<head>
</head>
<body>
<div id="serverData"></div>
</body>
<script type="text/javascript">
//check for browser support
if(typeof(EventSource)!=="undefined") {
//create an object, passing it the name and location of the server side script
var eSource = new EventSource("send_sse.php");
//detect message receipt
eSource.onmessage = function(event) {
//write the received data to the page
document.getElementById("serverData").innerHTML = event.data;
};
}
else {
document.getElementById("serverData").innerHTML="Whoops! Your browser doesn't receive server-sent events.";
}
</script>
</html>
send_sse.php:
<?php
header('Content-Type: text/event-stream');
header('Cache-Control: no-cache');
$val = 0;
if (isset($_POST['msg'])){
$val = $_POST['msg'];
}
echo "data: $val\n\n";
ob_flush();
?>
form.html:
<html>
<body>
<form action="send_sse.php" method="post">
Message: <input type="text" name="msg"><br>
<input type="submit">
</form>
</body>
</html>
The problem is that when the form posts the value, it does not update the output.html. It does output "0" and will update whenever I manually change the value of $val and save the file. However, I want the value of $val to be determined outside of the PHP file. What am I doing wrong?

The issue you are having here is that you have missed how SSE conceptually work. Your output.html page is making a GET request to your web server and executing the script send_sse.php and opening up a connection and HOLDING that connection open and waiting for updates.
When you are posting from form.html you are sending a POST request to your web server and executing the script send_sse.php on a completely different thread.
As you have not implemented any shared persistence between these two threads it will make no difference.
So to do what you want to do you will need to have code in send_sse.php that has some form of global persistence (e.g. database) and can detect new data and then flush that down to the browser.
I am not a PHP expert, but I have written an example in Node JS that uses REDIS pub/sub to provide said persistence.
I hope that helps.

Related

$.post() Get url of php in html

I am making an html script that will use jQuery.post() method in order to use a php script. The post() method needs an url of the php code but my php code is part of the html code
What Url should i use?
<html>
<body>
<button onclick="test()">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.2/jquery.min.js"></script>
<script>
var test = function() {
$('--I DONT KNOW--',{testvar:"hello"});
}
</script>
<?php
$testvar = $_POST['testvar'];
echo $testvar;
?>
</body>
</html>
An empty URL is a relative URL that resolves as the URL of the current page.
$.post("", {testvar:"hello"});
(Keep in mind that since your PHP does nothing with the data except output it, and your JS does nothing with the response, this will have no visible effect outside of the Network tab of your browser's developer tools).

Setting PHP variable in <noscript>

Something like the below does not work:
<?php $nojs = false; ?>
<noscript>
<?php $nojs = true; ?>
</noscript>
As the PHP is executed regardless if JS is enabled or not. But is there a way to get a similar effect? I'm trying to set a flag if JS is disabled and then display parts of the page accordingly.
PHP is executed before javascript, so you cannot do this. You can do something such as executing a basic ajax request and storing hasjs in a session variable once the ajax page is successfully queried. You wouldn't know if it's just the fact that the ajax request wasn't successful due to something else, or if they have Javascript disabled.
Lets give this a shot anyway:
The jquery script in your head tags
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.0/jquery.min.js"></script>
<script>
$( document ).ready(function() {
$.get( "hasjs.php", { hasjs: "1"} );
});
</script>
The PHP file (hasjs.php)
<?php
if(isset($_GET['hasjs']))
{
session_start();
$_SESSION['hasjs'] = 1;
}
?>
Then you can access the session variable to determine if they have JS based off the ajax query. Nothing stopping the user from visiting that page though if they don't have JS installed.

php: routine javascript browser does not appear until the end

We felt in a procedure in php to show a process bar while performing a task, but in the Chrome browser does not display the bar until the process ends. In other browsers like Chromium it works perfectly and shows the progress bar. Any suggestions?
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN">
<html lang="en">
<head>
<title>Progress Bar</title>
</head>
<body>
<!-- Progress bar holder -->
<div id="progress" style="width:500px;border:1px solid #ccc;"></div>
<!-- Progress information -->
<div id="information" style="width"></div>
<?php
// Total processes
$total = 10;
// Loop through process
for($i=1; $i<=$total; $i++){
// Calculate the percentation
$percent = intval($i/$total * 100)."%";
// Javascript for updating the progress bar and information
echo '<script language="javascript">
document.getElementById("progress").innerHTML="<div style=\"width:'.$percent.';background-color:#ddd;\"> </div>";
document.getElementById("information").innerHTML="'.$i.' row(s) processed.";
</script>';
// This is for the buffer achieve the minimum size in order to flush data
echo str_repeat(' ',1024*64);
// Send output to browser immediately
flush();
// Sleep one second so we can see the delay
sleep(1);
}
// Tell user that the process is completed
echo '<script language="javascript">document.getElementById("information").innerHTML="Process completed"</script>';
?>
</body>
I'm gonna be one of those annoying people that ask why are you doing something.
Do you actually need to stream the data from the server to the browser ?
Unless you are sending huge amounts of generated data to the user, there is really no need for such measures.
Because you are not using WebSockets, you could save the information about the process into the cookie, so that you do not have to store it anywhere else, and it is related to an individual client, and send an AJAX request to a dedicated page that will return the percentage, or the state of this process.
While the process is going on you just need to call setcookie with the correct values, something like
setcookie($name, $value, $expiration /*<--- does not matter*/);
and in the dedicated page that returns this value
return $_COOKIE[$name]; //<--- $name the same as in setcookie,
//this should probably return JSON
and in the js code you would ( with jquery, cause its easier )
$.get(page, function(data)
{
document.getElementById("progress").innerHTML =
'<div style="width: data;background-color:#ddd;"></div>';
}
Hope this helps.

window.location seems to cancel ajax post request

I am trying to send data to php with ajax and at the same time redirect to that php file but when I redirected to the php file, the ajax didn't seem to send the data. I wanted to achieve something wherein a button is clicked and a data is sent to php using ajax and at the same time redirect to that php file to see the data sent by displaying it. The reason I didn't use something like window.location="ajaxtest.php?data=data" is because I'm gonna be using it in a google map api wherein if I click a button of a place, then I will redirect to the maps page and display the marker of the specific place depending on the id the ajax sent to the php file and the coordinates generated based on that id.
ajaxtest.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
</head>
<body>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.3
/jquery.min.js"></script>
<script>
$(document).ready(function(){
$("#button").click(function(){
var data = "test";
$.post("ajaxtest.php",{
data: data
},function(data, status){
window.location="ajaxtest.php";
});
});
});
</script>
<button id="button">test</button>
</body>
</html>
ajaxtest.php
<?php
if(isset($_POST['data'])){
echo $_POST['data'];
}
?>
So, that's not how HTTP, AJAX, or PHP work. There isn't any POST data when you do your redirect, because the redirect is a separate request from the AJAX post. What you want is to do an AJAX post and somehow consume the response on your page, without doing a redirect at all.
It doesn't seem like ajax is the way to go here. If you want to redirect to a different page just do window.location.href = 'ajaxtest.php?id='+locationId; and in your ajaxtest.php:
<?php
$id = isset($_GET['id']) ? (int) $_GET['id'] : null;
if ( ! $id) {
die('ID missing');
}
// Show marker
?>

Session variable being set on my PC but not on webhost's server

I have the following code to check whether the client has javascript enabled in their browser:
page.php:
<?php
session_start();
if(isset($_SESSION['gocheck'])) {$gocheck = $_SESSION['gocheck'];}
else {$gocheck = 'no';}
//echo $gocheck;
if($gocheck=='no'){header ("Location: ./gocheck.php"); exit;}
//Only reaches this line if gocheck.php has been run and Javascript is enabled.
unset($_SESSION['gocheck']);
//rest of page
?>
gocheck.php:
<?php
session_start();
$_SESSION['gocheck'] = 'yes';
echo"
<!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\" xml:lang=\"en\" lang=\"en\">
<head>
<script type=\"text/javascript\" language=\"JavaScript\">
window.location.replace('page.php');
</script>
</head>
<body>
This website requires Javascript to be enabled in your browser. <br />
Please enable Javascript and try again.
</body>
</html>
";
?>
So what should happen is the user is always redirected from page.php to gocheck.php, which sets the session variable $gocheck to 'yes' and directs back to page.php via Javascript. Because $gocheck is then equal to 'yes', page.php shouldn't direct back again tio gocheck.php.
This worked fine on my PC (using WAMP), but when I upload the files to the webhost, it seems to get stuck in an infinite redirect loop between page.php and gocheck.php. Also, if I echo $gocheck in page.php, it returns 'no', so it seems as if for some reason the session variable $gocheck is not being set properly by gocheck.php.
Could somebody please shed some light on this? Is there an error in my code? Is there something I need to change in php.ini on the webhost's server?
Thanks!
P.S. WAMP on my PC uses PHP v.5.3.0, but the webhost uses PHP v.5.2.12 - don't think this can be the problem though.
Why using php to detect if javascript is enabled or not? You can just add following html tags to your page:
<noscript>
Pleas enable javascript!
</noscript>
If the user then enables javascript and refreshes the page the javascript code will work.
ok never mind, now all session variables are being set properly, maybe it was just a question of waiting a bit until the webhost configured everything correctly (also had this problem with setting up e-mails)

Categories