I searched online to find a solution for refreshing user cache if the website has been updated. Couldn't find anything apart from setting version control on url of the script files...
I'm answering my question below, and need to know if this is a perfect code and might not keep refreshing in a loop. Please could someone let me know if any modifications are required?
My answer involves
a php script that checks selected files on the server for modification date.
on the html page, javascript gets the data from php via jQuery getJSON.
Then it checks for localstorage data regarding the files, this data is first stored if none found via html5 localstorage.
Then it compares dates between localstorage and php jSON data.
If there are new files on the server, it stores the new dates instead of the old dates on the localstorage for future visits.
Refreshes only if newer versions of the scripts are found.
Below is the code, and here's the jsfiddle: [ ::: jsfiddle ::: ]
Snippet is not allowing localStorage, instead try js fiddle: '/xepjcwsf/'
//Script to check (via php & javascript), if the files loaded into client's cache are old and refreshes the page if newer files found on the server.
$(document).ready( function() {
var newFileCacheDate;
//uncomment: //$.getJSON('scripts/file_date.php', function(jsonData){
setTimeout(function(){
newFileCacheDate = {"css_1":"30-01-2015","css_2":"28-01-2015","css_3":"07-03-2015","js_1":"28-02-2015","js_2":"02-03-2015"}; //uncomment: //jsonData;
var StoredData = getStorage();
var isUpdated = check_filedate(newFileCacheDate, StoredData);
if(isUpdated) {
console.log('files have been updated, isUpdated = true');
addNewStorage_and_refresh(newFileCacheDate);
}
//uncomment: //}).fail(function() { console.log( "Couldn't get the json data." ); });
}, 1000);
function addNewStorage_and_refresh(newDates){
if(typeof(Storage) !== "undefined") {
localStorage.setItem('filecache_date', JSON.stringify(newDates));
alert('filedate storage updated, refreshing');
location.reload();
}
}
function getStorage(){
if(typeof(Storage) !== "undefined") {
var fileCacheDate, stored_FileDates;
var dataToStore = {
"css_1" : '30-01-2014',
"css_2" : '28-01-2015',
"css_3" : '07-03-2015',
"js_1" : '28-02-2015',
"js_2" : '02-03-2015'
};
if (localStorage.getItem("filecache_date") === null) {
localStorage.setItem('filecache_date', JSON.stringify(dataToStore));
console.log('filecache=null');
return dataToStore;
}
else if (localStorage.getItem("filecache_date") != null) {
fileCacheDate = localStorage.getItem('filecache_date'),
stored_FileDates = JSON.parse(fileCacheDate);
console.log('filechache=present');
return stored_FileDates;
}
}
}
function check_filedate(newfile, oldfile){
var isItUpdated = false;
$.each(oldfile, function (key, olddata) {
if(Date.parse(process(olddata)) < Date.parse(process(newfile[key]))){
console.log('files have been updated = true');
isItUpdated = true;
return false;
}
});
return isItUpdated;
function process(date){ var parts = date.split("-"); return new Date(parts[2], parts[1] - 1, parts[0]); } //to convert and return date in standard format
}
});
/* THE PHP CODE
** Paste this PHP code as a separate "file_data.php" file for retrieving json data from **
*******************************************************************************************
<?php
$filenames = array(
"css_1" => 'file1_css.css',
"css_2" => 'file2_css.css',
"js_1" => 'file3_jscript.js',
"js_2" => 'file4_jscript.js'
);
$previousDate = array(
"css_1" => '0',
"css_2" => '0',
"js_1" => '0',
"js_2" => '0',
);
foreach ($filenames as $jsonVar => $filename) {
if (file_exists($filename)) {
$mtime = filemtime($filename);
$previousDate[$jsonVar] = date ("d-m-Y", $mtime);
}
}
echo json_encode($previousDate);
?>
*******************************************************************************************
*/
//Below code for demo purpose only.
$(document).ready( function() {
$('button#reset').on('click', function(){
localStorage.removeItem('filecache_date');
location.reload();
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<!-- Check Console for Logs -->
Check Console for Logs
<br><br>
If you were unable to see console log before page refresh, click on the reset button
<br>
(page will refresh after resetting localStorage data)
<br><br>
<button id="reset">Reset </button>
<br><br>
EDIT: Although jsfiddle allows localstorage, the stackoverflow snippet tool doesn't allow it, so this code might not function on stackoverflow.<br><br>
<b style="color:red;">Uncaught SecurityError: Failed to read the 'localStorage' property from 'Window': The document is sandboxed and lacks the 'allow-same-origin' flag.</b>
Related
I want to load the js file after redirect to destination in drupal. I have created a custom module with a hook_user_login.I have redirect a page in successful login and want to load a js file after redirect.now file loads in between login success and until redirect.
function one_time_popup_user_login(&$edit, $account){
$userName='test';
if(!isset($_COOKIE[$userName])){
$count=1;
if($count==1)
{
drupal_add_js(array('one_time_popup' => array('aniv' => $anniversaryCount,'userName'=>$userName,'celeType'=>'Anniversary')), array('type' => 'setting'));
drupal_add_js(drupal_get_path('module', 'one_time_popup') . '/celebrationPopup.js','file');
$settings=variable_get('one_time_popup_effects',unserialize(ONE_TIME_POPUP_DEFAULT));
drupal_add_js(array('onetimepopupmenu'=>$settings),'settings');
setcookie($userName, '1', time()+(24 *3600));
}
if (!isset($_GET['destination'])) {
$_GET['destination'] = drupal_get_destination(); //get the current url
}
}
}
I think you need to have the JS in your destination page. And tell that page when to run it. Or add it in a hook that targets that particular page.
First I would include some extra validation in your hook so the redirect doesn't happen when a user is trying to recover the password.
See how I am checking for the 'user_pass_reset' form id in the following exampes:
Firing the JS using another JS function
function one_time_popup_user_login(&$edit, $account) {
if (!isset($_POST['form_id']) || $_POST['form_id'] != 'user_pass_reset') {
$_GET['destination'] = 'your/custom/path#celebrationpopup';
}
}
Notice how I've added a hash (#celebrationpopup) to the destination url.
We will use this later in our destination page to run the JS function that we need.
Example jQuery code you need to place in the destination page. For this to work you need to have the function one_time_popup() already loaded in your code. This is just an example.
$(document).ready(function() {
//Get hash from URL
var hash = location.hash;
if (hash == '#celebrationpopup') {
one_time_popup();
}
});
Another option: Using a hook
If your destination page is a node you can use:
function one_time_popup_user_login(&$edit, $account) {
if (!isset($_POST['form_id']) || $_POST['form_id'] != 'user_pass_reset') {
$_GET['destination'] = 'your/custom/path?celebrationpopup=true';
}
}
function one_time_popup_node_view($node, $viewmode, $langcode) {
if($node->type == 'some_type' && isset ($_GET["celebrationpopup"])) // You can also use a node ID.
{
drupal_add_js(array('one_time_popup' => array('aniv' => $anniversaryCount,'userName'=>$userName,'celeType'=>'Anniversary')), array('type' => 'setting'));
$node->content['#attached']['js'][] = array
(
'type' => 'file',
'data' => drupal_get_path('module', 'one_time_popup') . 'js/celebrationPopup.js',
);
}
}
You might as well use a page preprocess function.
Hope this is clear.
Situation:
I am reading the content of a .txt file with php and with AJAX i load the content into a div. The javascript checks every 5 seconds the .txt file and put the content into the div.
If the content of the .txt file changes, (which i do with a form submit), the content of the div changes automatically after 5 seconds.
For this; i use a checkbox with 3 options:
Status: Available
Status: Busy
Status: Paused
One of the 3 lines above is in the .txt file.
Situation now: every 5 seconds check of the .txt file and every 5 seconds refresh of the div. Is it possible that if the content of the .txt file has not changed, to keep the refresh away?
How can i achieve this?
Below the javascript:
function Ajax()
{
var
$http,
$self = arguments.callee;
if (window.XMLHttpRequest) {
$http = new XMLHttpRequest();
} else if (window.ActiveXObject) {
try {
$http = new ActiveXObject('Msxml2.XMLHTTP');
} catch(e) {
$http = new ActiveXObject('Microsoft.XMLHTTP');
}
}
if ($http) {
$http.onreadystatechange = function()
{
if (/4|^complete$/.test($http.readyState)) {
document.getElementById('ReloadThis').innerHTML = $http.responseText;
setTimeout(function(){$self();}, 5000);
}
};
$http.open('GET', 'loadtxt.php' + '?' + new Date().getTime(), true);
$http.send(null);
}
}
Loadtxt.php
<?php
//
$file = "status.txt";
$f = fopen($file, "r");
while ( $line = fgets($f, 5000) ) {
echo $line;
}
?>
The div:
<script type="text/javascript">
setTimeout(function() {Ajax();}, 5000);
</script>
<div id="ReloadThis">Default text</div>
Calculate the HASH of the file on the server-side have your AJAX check with the for the hash (say a SHA1 or an MD5) - and only update the DIV if the hash has changed since it last looked ?
Maybe this PHP function on the server could help here ?
string hash_file ( string $algo , string $filename [, bool $raw_output = false ] )
Which I found on this link : http://php.net/manual/en/function.hash-file.php
So something like this (I am not in a position to test this; so edits are very welcome here):
filehash.php:
<?php
$file = "status.txt";
echo hash_file( "SHA1", $file, $raw_output=false )
?>
Set up a Javascript variable like 'fileHash':
var fileHash;
populate with an AJAX call to the new PHP script:
[...]
$http.open('GET', 'filehash.php' , true);
newFileHash=$http.responseText;
if (fileHash!=newFileHash) { // file changed - so fetch contents
[...]
// check me here: can we just make use of $http twice here ?
$http.open('GET', 'loadtxt.php' + '?' + new Date().getTime(), true);
// update div.
document.getElementById('ReloadThis').innerHTML =$http.responseText;
fileHash=newFileHash;
}
setTimeout(function(){$self();}, 5000);
[...]
Alternative suggestion:
Your webserver might be able to automatically return a HTTP code to state that the file hasn't changed since it was last requested (by comparing with your browser headers) - with an HTTP 304 for instance:
From Wikipedia:
304 Not Modified
Indicates that the resource has not been modified since the version specified by the request headers If-Modified-Since or
If-None-Match. This means that there is no need to retransmit the
resource, since the client still has a previously-downloaded copy.
It looks like you have added a timestamp parameter to your GET request - which I presume is prevent your browser caching the old copy of the text file: if you do opt for the method above, you should remove this from your GET request - as this will appear to the webserver that you are asking for a new document each time.
I m trying to post the value from my java_post.js into php_post.php and then retrieve in another javascript page, index.html. So far i can post the value into the php_post.php and retrieve back into my java_post.js as alert(data)
but i cannot retrieve from my index.html
Java_post.js
var url_link ="index.html";
//On Click Select Function
$("#table_hot").on('click', 'tbody tr',function(){
$(this).addClass('selected').siblings().removeClass('selected');
var value=$(this).find('td:first').html();
$.post('PHP_post/php_post.php',
{
postvalue:value
},
function(data){
alert(data);
}
);
});
//Window Pop Out Function
function hotspot_pop(url_link){
newwindow = window.open(url_link, '', "status=yes,
height=500; width=500; resizeable=no");
}
The value is retrieve when the client click the selected table and then post into the php_post.php. The php_post.php will filter the result and return to index.html.
$filtered_students = array_filter($ARRAY, function($row) {
$hotspot_value = $_POST['postvalue'];
if($row['name'] == $hotspot_value){
return true;
}
});
echo $filtered_students;
So now i m able to retrieve the value and post into as an alert for my java_post.js but the value is no pass into index.html and i receive the error for undefined postvalue.
<html>
<script src="js/jquery-1.11.1.min.js"></script>
<body>
<div id="result"></div>
<script>
var xmlhttp_user = new XMLHttpRequest();
var url_user = "PHP_post/php_post.php";
xmlhttp_user.onreadystatechange=function() {
if (xmlhttp_user.readyState == 4 && xmlhttp_user.status == 200) {
document.getElementById("result").innerHTML=xmlhttp_user.responseText; }
}
xmlhttp_user.open("GET", url_user, true);
xmlhttp_user.send();
</script>
</body>
</html>
So my problem is now, is there any method that allow me to show the value in index.html from php_post.php. As a reminder the alert(data) from java_post.js is just a testing purpose to show the value did post and return from php_post.php
The issue you're having is that when you pass the data into your PHP file and receive the data back in your JavaScript, the information only lasts as long as your current request.
To fix this issue, consider using PHP Session variables to store your data, so that you can retrieve it later.
Example:
// php_post.php
<?php
start_session(); // initializes session for persistent data
$filtered_students = array_filter($ARRAY, function($row) {
$hotspot_value = $_POST['postvalue'];
if($row['name'] == $hotspot_value){
return true;
}
});
$_SESSION["filtered_students"] = $filtered_students; // You can now retrieve this in
// Another PHP file
?>
Now in another file (you would switch your HTML file to get from php_get.php):
//php_get.php
<?php
start_session(); // Don't forget to start the session
echo $_SESSION['filtered_students'];
?>
More information here: http://www.w3schools.com/php/php_sessions.asp
You can set the desired value into PHP session while at php_post.php.
This way, you can retrieve the session's value on any page you desire.
I have the following code in my main Dancer app .pm:
package Deadlands;
use Dancer ':syntax';
use Dice;
our $VERSION = '0.1';
get '/' => sub {
my ($dieQty, $dieType, $bonus);
my $button = param('button');
$dieQty = param('dieQty');
$dieType = param('dieType');
$bonus = param('bonus');
if (defined $dieQty && defined $dieType) {
return Dice::Dice->new(dieType => $dieType, dieQty => $dieQty, bonus => $bonus)->getStandardResult();
}
template 'index';
};
true;
Here is my JavaScript:
$(document).ready(function() {
$('#standardRoll').click(function() {
$.get("/lib/Deadlands.pm", { button: '1', dieType: $("#dieType").val(), dieQty: $("#dieQty").val(), bonus: $("#bonus").val() }, processData);
function processData(data) {
$("#result").html(data);
}
});
});
I have a div in my web page called result that I want to be updated with the die roll result from Perl. Dancer keeps coming back with a 404 error in the command window when I push the submit button.
/lib/Deadlands.pm needs to be the URL of your route (probably / in this case), not the filesystem path of your Perl module.
Your AJAX request needs to point to a URL that actually exists, not a filename that has nothing to do with the web. Looks like $.get('/', ...) would do in this case.
My ASPX code generated some html files where I just put link for paging like
First |
Next |
Previous |
Last
say if user currently on second page when it press Next moves to 3rd page ...
now issue is when user clicking Next button several times and system is in progress to generate let say 5th page it will show error page.
Is there any way to check from html via javascript to check whether file is present or not?
Kindly help me to pull out from this show stopper issue
You can use ajax for check file exists or not
Using Jquery
$.ajax({
url:'http://www.example.com/3.html',
error: function()
{
alert('file does not exists');
},
success: function()
{
alert('file exists');
}
});
Using Javascript
function checkIfRemoteFileExists(fileToCheck)
{
var tmp=new Image;
tmp.src=fileToCheck;
if(tmp.complete)
alert(fileToCheck+" is available");
else
alert(fileToCheck+" is not available");
}
Now to check if file exists or not call js function like this
checkIfRemoteFileExists('http://www.yoursite.com/abc.html');
i like to use this type of script
function CheckFileExist(fileToCheck: string) {
return new Promise((resolve, reject) => {
fetch(fileToCheck).then(res => {
if (res.status == 404) resolve(false);
if (res.status == 200) resolve(true);
return res.text()
})
})
}
and use it
var exists = await CheckFileExist(link);
There is an issue with #Sibu's solution: it actually downloads the file (it can be potentionally big, wasting traffic)
In the 2021, one should not use jQuery in new projects
native Promises and Fetch are the way to go today
<output id="output"></output>
<script>
// create a non-cached HTTP HEAD request
const fileExists = file =>
fetch(file, {method: 'HEAD', cache: 'no-store'})
.then(r => r.status==200);
// check the file existence on the server
// and place the link asynchronously after the response is given
const placeNext = file => fileExists(file).then(yes => output.innerHTML =
(yes ? `Next` : '')
);
// place the "next" link in the output if "3.html" exists on the server
placeNext('3.html');
</script>