Can i do a scheduled task programming with javascript? - javascript

I want to do a sheduled task for every day.I have multiple servers and i want to automate the upload of html file to my other servers.In this case i have on the same folder my html and my script.js.Im currently using ajax to upload the html file but i want to do that without interference.Here is my javascript.
$(function(){
$("#drop-box").click(function(){
$("#upl").click();
});
// To prevent Browsers from opening the file when its dragged and dropped on to the page
$(document).on('drop dragover', function (e) {
e.preventDefault();
});
// Add events
$('input[type=file]').on('change', fileUpload);
// File uploader function
function fileUpload(event){
$("#drop-box").html("<p>"+event.target.value+" uploading...</p>");
files = event.target.files;
var data = new FormData();
var error = 0;
for (var i = 0; i < files.length; i++) {
var file = files[i];
console.log(file.type);
if(!file.type.match('html.*')) {
$("#drop-box").html("<p> Html only. Select another file</p>");
error = 1;
}else if(file.size > 1048576){
$("#drop-box").html("<p> Too large Payload. Select another file</p>");
error = 1;
}else{
data.append('html', file, file.name);
}
}
if(!error){
var xhr = new XMLHttpRequest();
xhr.open('POST', 'upload.php', true);
xhr.send(data);
xhr.onload = function () {
if (xhr.status === 200) {
$("#drop-box").html("<p> File Uploaded. Select more files</p>");
} else {
$("#drop-box").html("<p> Error in upload, try again.</p>");
}
};
}
}
This script work fine with my server side, but i want to be able to perform this html upload every day.Is this possible ? what about SetInterval and SetTimeout ?

You can schedule tasks with JavaScript so that they are executed in specific intervals. But you can not upload files from the local system to the server:
JavaScript can't start file transfers on it's own due to security reasons and always needs manual user interaction to do this.
The reason why your above script works is because fileUpload() is orginally triggered by the user. As soon as you use timeout() or interval(), the browser detects that the operation was not triggered by the user and won't allow you to upload user data.

Related

Limitations for controlling files with JavaScript

Please excuse me for not being good at English because I do not live in an English-speaking country.
I am student, and I want to make code for file encryption and download that file with jquery(in client side).
I solved it, but I have some problems.
When I upload file for encrypting file that has big size,
my site is crashed.
(My code will be applied to a simple homepage.)
When I run that process in firefox or icedragon browser, I can see error that 'allocation size overflow'.
Can you tell me why that problem happened?
The code I wrote is below and the reference address is here.
$(function(){
var body = $('body'),
stage = $('#stage'),
back = $('a.back');
/* Step 1 */
$('#step1 .encrypt').click(function(){
body.attr('class', 'encrypt');
// Go to step 2
step(2);
});
$('#step1 .decrypt').click(function(){
body.attr('class', 'decrypt');
step(2);
});
/* Step 2 */
$('#step2 .button').click(function(){
// Trigger the file browser dialog
$(this).parent().find('input').click();
});
// Set up events for the file inputs
var file = null;
$('#step2').on('change', '#encrypt-input', function(e){
// Has a file been selected?
if(e.target.files.length!=1){
alert('Please select a file to encrypt!');
return false;
}
file = e.target.files[0];
/*if(file.size > 1024*1024*50){
alert('Please choose files smaller than 50mb, otherwise you may crash your browser. \nThis WARNING is for you.');
return;
}*/
step(3);
});
$('#step2').on('change', '#decrypt-input', function(e){
if(e.target.files.length!=1){
alert('Please select a file to decrypt!');
return false;
}
file = e.target.files[0];
step(3);
});
/* Step 3 */
$('a.button.process').click(function(){
var input = $(this).parent().find('input[type=password]'),
a = $('#step4 a.download'),
password = input.val();
input.val('');
if(password.length<5){
alert('Please choose a longer password!');
return;
}
// The HTML5 FileReader object will allow us to read the
// contents of the selected file.
var reader = new FileReader();
if(body.hasClass('encrypt')){
// Encrypt the file!
reader.onload = function(e){
// Use the CryptoJS library and the AES cypher to encrypt the
// contents of the file, held in e.target.result, with the password
var encrypted = CryptoJS.AES.encrypt(e.target.result, password);
var encryptedFileArray = [encrypted];
var blob = 'Blob Data';
var fileName = file.name + '.encrypted';
if(window.navigator.msSaveOrOpenBlob) {
window.navigator.msSaveOrOpenBlob(blob, fileName);
} else {
var blobEncrypted = new Blob(encryptedFileArray, { type: 'application/octet-stream' });
var blobUrl = URL.createObjectURL(blobEncrypted);
$(a).attr({
'download': file.name + '.encrypted',
'href': blobUrl
});
}
// The download attribute will cause the contents of the href
// attribute to be downloaded when clicked. The download attribute
// also holds the name of the file that is offered for download.
step(4);
};
// This will encode the contents of the file into a data-uri.
// It will trigger the onload handler above, with the result
reader.readAsDataURL(file);
}
else {
// Decrypt it!
reader.onload = function(e){
var decrypted = CryptoJS.AES.decrypt(e.target.result, password).toString(CryptoJS.enc.Latin1);
if(!/^data:/.test(decrypted)){
alert("Invalid pass phrase or file! Please try again.");
return false;
}
var url = decrypted;
var userAgent = navigator.userAgent;
var filename = file.name.replace('.encrypted','');
var xhr = new XMLHttpRequest();
xhr.responseType = 'blob';
xhr.onload = function () {
$(a).attr({
'download': filename,
'href': window.URL.createObjectURL(xhr.response) // xhr.response is a blob
});
};
xhr.open('GET', url);
xhr.send();
step(4);
};
reader.readAsText(file);
}
});
/* The back button */
back.click(function(){
// Reinitialize the hidden file inputs,
// so that they don't hold the selection
// from last time
$('#step2 input[type=file]').replaceWith(function(){
return $(this).clone();
});
step(1);
});
// Helper function that moves the viewport to the correct step div
function step(i){
if(i == 1){
back.fadeOut();
}
else{
back.fadeIn();
}
// Move the #stage div. Changing the top property will trigger
// a css transition on the element. i-1 because we want the
// steps to start from 1:
stage.css('top',(-(i-1)*100)+'%');
}
});
xhr.open('GET', url);
you are using GET method. maybe is better using POST instead.
what is your server side language? is it PHP?
if that is PHP, should be better check the file upload size in "php.ini" file.

Constantly read local file with JS?

I've been looking all over the place but I can't find a solution to reading a local text file (in the same folder as my js and html files) repeatedly that works with Chrome.
I need to constantly read the file for updates, which another program updates automatically, I don't know how. It's just a regular text.txt file.
I've read a lot of questions/answers on here about it, but so far I've found nothing. Can anyone help?
edit: I meant without node as well, just vanilla JS.
You can enable XmlHttpRequest for local files by starting Chrome with it's security features disabled. This is not an ideal solution but it is the only way to automatically do what you want without running some kind of server. Using Node to watch the file for changes and pushing the data over a WebSocket to the browser would be the proper way to handle this.
Alternatively you could use the FileReader API to open this local file but you need to select it manually through an <input type="file"> element first.
function readInputFile(event) {
let file = event.target.files[0];
if (!file) {
return;
}
let reader = new FileReader();
reader.addEventListener('load', event => {
let content = event.target.result;
alert(content);
});
reader.readAsText(file);
}
document.getElementById('datafile').addEventListener('change', readInputFile, false);
<input type="file" id="datafile">
Edit:
It's 2022 now and we have another way to accomplish this using the File System Access API. It's currently not available in Firefox but this method could be useful if you're only targeting Chromium based browsers (for example: in an Electron app). Note that this feature is only available in secure contexts such as from localhost or over https.
<!DOCTYPE html>
<title> File System Access API Test </title>
<button id="pick"> Pick File </button>
<button id="stop" disabled> Stop Watching </button>
<script>
const pickButton = document.querySelector('button#pick');
const stopButton = document.querySelector('button#stop');
let selected, i;
let pollRate = 15; // seconds
pickButton.addEventListener('click', accessFile);
stopButton.addEventListener('click', stopWatching);
async function accessFile() {
stopWatching();
let [fileHandle] = await window.showOpenFilePicker();
if (fileHandle) {
let f = await fileHandle.getFile();
if (!f) { console.log('failed accessing file'); return ; }
selected = { handle : fileHandle, file : f };
console.log('selected', f.name);
readFile(f);
startWatching();
} else {
console.log('no file selected');
}
}
async function checkFile() {
if (!selected) { return; }
let f = await selected.handle.getFile();
if (f.lastModified > selected.file.lastModified) {
console.log(selected.file.name, 'was updated');
selected.file = f;
readFile(f);
} else {
console.log(selected.file.name, 'had no changes');
}
}
function readFile(f) {
let reader = new FileReader();
reader.addEventListener('load', event => {
console.log(event.target.result);
}); reader.readAsText(f);
}
function startWatching() {
if (i) { clearInterval(i); }
stopButton.disabled = false;
i = setInterval(async ts => {
if (!selected) { return; }
checkFile();
}, pollRate * 1000);
}
function stopWatching() {
clearInterval(i);
i = null;
selected = null;
stopButton.disabled = true;
}
</script>
I think you might be confused what a 'local' file is in this context.
A local file will be loaded with a url such as file://, or selected from a file input in a form.
A file next to your .html and .css is not a local file, it's a hosted file on your web server what you're using to host the .html. You would be referring to it with a relative path to your domain, such as '/file.css'
Node would have more options, seeing that it can read and access local files synchronously with the build in fs ( file system ) library.
What you'll need to do is treat your file like any other on the internet, and download it the same way. Then, download it again later when you need to check for updates. repeat.

How to show a spinner while making an HTTP request (Appcelerator)

Currently, I am trying to show a spinner while making an HTTP request that will end when the call completes. I have built several different spinners but all stop animation the second the call begins.
var spinnerArray = [];
for (var i = 0; i < 20; i++) {
spinnerArray.push('/images/preloaderGif/preloader'+ ("0" + i).slice(-2) + '.gif');
}
$.spinner.images = spinnerArray;
$.spinner.duration = "200";
$.spinner.repeatCount = "0";
spin();
function spin(){
$.spinner.start();
callHTTP() //Prewritten function
Ti.App.addEventListener('callEnd', function(e){
$.spinner.stop();
});
}
This results in the spinner never appearing. Taking the call out or nesting it within a timeout causes the spinner to spin infinitely, or until the timeout ends.
Is there a way to have the spinner continue to spin through the call?
Actually, there's a far better & super easy way to show an indicator. Just follow below steps.
Download this widget Loading Indicator Widget & add it to your project in app->widgets folder. Create widget folder if it doesn't exist.
Add this line "nl.fokkezb.loading" : "*" into your app->config.json file within dependencies dictionary as shown in below screenshot.
Add this line Alloy.Globals.loading = Alloy.createWidget("nl.fokkezb.loading"); in your alloy.js file
Finally, you can use this code to show/hide indicator properly while calling HTTP requests.
function callHTTP() {
if (!Ti.Network.online) {
return;
}
Alloy.Globals.loading.show();
var xhr = Ti.Network.createHTTPClient({
onerror : function(e) {
Alloy.Globals.loading.hide();
},
onload : function(e) {
Alloy.Globals.loading.hide();
// run your additional code here
},
});
xhr.open("GET", url);
xhr.send();
}
callHTTP();
Using this widget, you won't need to write long, error-prone codes for different projects. Just add this widget & you can show/hide loading indicator with just 2 lines of code.
Remember one thing that XHR error/success callbacks are the only places where you can write code to hide the indicators as you can never be sure when the HTTP request will complete.
You could use an ActivityIndicator : http://docs.appcelerator.com/platform/latest/#!/api/Titanium.UI.ActivityIndicator
$.activityIndicator.show();
var xhr = Ti.Network.createHTTPClient({
onerror : function(e) {
// code
$.activityIndicator.hide();
},
onload : function(e) {
// code
$.activityIndicator.hide();
},
});
xhr.open("GET", url);
xhr.send();

Nonsensical values of loaded and total in AJAX file upload

I am trying to build a progress bar for multiple files drag and drop upload by combining code from tutorial on multiple files drag and drop uploading and tutorial on progress bar uploading.
Javascript part is:
var dropzone = document.getElementById("dropzone");
function updateProgress(e){
document.getElementById("progress").innerHTML = e.loaded + " of " + e.total;
}
function upload(files){
var formData = new FormData(),
xhr = new XMLHttpRequest(),
x;
for(x = 0; x < files.length; x++){
formData.append("file[]", files[x]);
}
xhr.addEventListener("progress", updateProgress, false);
xhr.open("post", "upload.php");
xhr.send(formData);
}
dropzone.ondrop = function(e){
e.preventDefault();
this.className = "dropzone";
upload(e.dataTransfer.files);
}
dropzone.ondragover = function(){
this.className = "dropzone dragover";
return false;
}
dropzone.ondragleave = function(){
this.className = "dropzone";
return false;
}
And upload.php is simply:
<?php
if(!empty($_FILES["file"]["name"][0]))
foreach($_FILES["file"]["name"] as $position => $name)
move_uploaded_file($_FILES["file"]["tmp_name"][$position], "uploads/".$name);
?>
For start, before making actual progress bar, I just want to show the number of uploaded and total bytes. However, function updateProgress doesn't get called if upload.php echoes nothing and otherwise (e.g. if I add echo "something";) e.loaded and e.total are small numbers of same value, unrelated to file size.
File upload itself works fine, even with large files (few hundred MBs). With large files, I've noticed that function updateProgress is called only once - after the upload is complete.
Why is this event handling behaving like this and how to fix it?
You are setting a progress handler for download, to set one for upload use
xhr.upload.addEventListener("progress", updateProgress, false);

problem in calling cgi from javascript

I am executing a cgi file directly from javascript onclick of a button. The cgi return the doc, xls, exe etc file which in turn opens SavaAs dialog to let the client save file on his machine.
Problem comes when multiple cgi files are executing in a for/while loop, It executes only the first cgi and opens the SaveAs dialog, but once the SaveAs opens it does not enter into the "for" loop again to execute another cgi which opens SaveAs dialog .
Here is the code fragment -
for(i = 0; i < dataPopup.elements['checkbox'].length; i++)
{
j=0;
obj = dataPopup.elements['checkbox'];
if(obj[i].checked)
{
var temp=obj[i].value;
temp = temp.split(".");
if(temp[1] == "txt")
{
saveWins[temp[1]] = setTimeout("document.location='../cgi/saveTextFile.cgi?fname=070319185708701_1'", 100);
}
else if(temp[1] == "pdf")
{
saveWins[temp[1]] = setTimeout("document.location='../cgi/savePdfFile.cgi?fname=065726729272220_1'", 100);
}
else if(temp[1] == "xls")
{
saveWins[temp[1]] = setTimeout("document.location = '../cgi/saveXlsFile.cgi?fname=288433243743'", 100);
}
else if((temp[1] == "doc") || (temp[1] == "docx"))
{
saveWins[temp[1]] = document.location = '../cgi/saveDocFile.cgi?fname='+temp[0];
}
saveWins[temp[1]].focus();
}
}
Please Help.
Setting document.location replaces the current document with the new document - even if it's a download. That means there is no longer a script to continue to execute.
You'll need to set the location of an iframe instead.
RoToRa means that instead of using document.location you should insert a hidden iFrame in your page and change the location of the iframe using window.frames[iframeName].location.

Categories

Resources