I am Java developer by birth with very limited hands on client side programming, so need help here.
I am basically looking for a way to create single page HTML/JavaScript application to read my local file system. I want to list directories and files within specific directory on my HTML page. What are the ways to achieve this.
Please note that I want to avoid server side coding or web application and stuff. Just need plain HTML and/or Javascript or any Javascript framework to do this for me. And I need it to be working primarily on chrome.
Please suggest.
Though its not a good to read the files at client side lot of security and access issues may occur. Still if you want you Can read the file at client side using filereader,check the following example:
<input type="file" id="fileinput" multiple />
<script type="text/javascript">
function readMultipleFiles(evt) {
//Retrieve all the files from the FileList object
var files = evt.target.files;
if (files) {
for (var i=0, f; f=files[i]; i++) {
var r = new FileReader();
r.onload = (function(f) {
return function(e) {
var contents = e.target.result;
console.log(contents);
alert( "Got the file.n"
+"name: " + f.name + "n"
+"type: " + f.type + "n"
+"size: " + f.size + " bytesn"
+ "starts with: " + contents.substr(1, contents.indexOf("n"))
);
};
})(f);
r.readAsText(f);
}
} else {
alert("Failed to load files");
}
}
document.getElementById('fileinput').addEventListener('change', readMultipleFiles, false);
</script>
Related
I am facing a small issue here...
I want to write a javascript function to open files with different extensions, I have already written a function that can open files but with their extensions hard written in the code, how to make this dynamic? Like Instead of opening "file1.pdf" or "file1.png" I want to store the extension as a variable and open it dynamically.
Here is the code:-
<script>
function viewCM() {
var transferID = document.getElementById("theTransferID").value;
$.get("/Uploads/" + transferID + ".pdf")
.done(function () {
// Do something now you know the file exists.
window.open("/Uploads/" + transferID + ".pdf", '_blank', 'fullscreen=yes');
}).fail(function () {
// File doesn't exist - do something else.
alert("File was not found");
})
return true;
}
</script>
The above function works perfectly with any type of extension but I can't manage to know how to make the extension dynamic
Thanks in advance
EDIT: I don't get the file name from the server, The idea is simply that I have an upload button that uploads a file related to a specific "transfer" and I make the name of the uploaded file as transferID.whatever extension then when I want to open the file, I just write the code I posted. so I don't search the server for the file name.
Following up on comments in the original question:
function viewCM(fileExtension) {
var transferID = document.getElementById("theTransferID").value;
$.get("/Uploads/" + transferID + "." + fileExtension)
.done(function () {
// Do something now you know the file exists.
window.open("/Uploads/" + transferID + "." + fileExtension, '_blank', 'fullscreen=yes');
}).fail(function () {
// File doesn't exist - do something else.
alert("File was not found");
})
return true;
}
You should not need to have any if statements within viewCM() if you can pass the file extension to the function (unless you're planning on performing some type of validation).
It will automatically adjust according to file type.
means if pdf then open pdf viewer, excel should open excel
window.open( file Name );
Maybe you could find whats after the dot in the name to search for the type, just an idea.
var afterDot = str.substr(str.indexOf('.'));
Then depending on type do your code.
(This can be very much improved).
EDITED:
var transferID = document.getElementById("theTransferID").value;
var extension = transferID.substr(transferID.indexOf('.'));
Now you have this possibility:
if(extension == ".pdf"){ $.get("/Uploads/" + transferID + ".pdf")
.done(function () {//...}
For anyone facing the same issue, I have made a some kind of "naive" workaround to solve this by making multiple JavaScript functions to open various types of files.
It is as simple as : try to read a pdf file, if you can't then call a function that reads a png file etc!!
<script>
function viewCM() {
var transferID = document.getElementById("theTransferID").value;
$.get("/Uploads/" + transferID + ".pdf")
.done(function () {
// Do something now you know the file exists.
window.open("/Uploads/" + transferID + ".pdf", '_blank', 'fullscreen=yes');
}).fail(function () {
// File doesn't exist - call the next function.
viewCMPng();
})
return true;
}
function viewCMPng() {
var transferID = document.getElementById("theTransferID").value;
$.get("/Uploads/" + transferID + ".png")
.done(function () {
// Do something now you know the file exists.
window.open("/Uploads/" + transferID + ".png", '_blank', 'fullscreen=yes');
}).fail(function () {
// File doesn't exist - show alert message.
alert("File was not found");
})
return true;
}
</script>
I need a way to get all the images from a local folder for a presentation that will also run locally. There will be no attempt for a server to take the images from a local folder since that is not possible/the case.
I need to use .js since I can't use .php (which would be easier) since it runs on a local PC.
Say I need to take all the images from learn/
I have tried various solutions that can be found here, here and here but none worked.
I think your best option is to use the new File API in Javascript. Is has a lot of functions to read files from the file system.
<input type="file" id="fileinput" multiple />
<script type="text/javascript">
function readMultipleFiles(evt) {
//Retrieve all the files from the FileList object
var files = evt.target.files;
if (files) {
for (var i=0, f; f=files[i]; i++) {
var r = new FileReader();
r.onload = (function(f) {
return function(e) {
var contents = e.target.result;
alert( "Got the file.n"
+"name: " + f.name + "n"
+"type: " + f.type + "n"
+"size: " + f.size + " bytesn"
+ "starts with: " + contents.substr(1, contents.indexOf("n"))
);
};
})(f);
r.readAsText(f);
}
} else {
alert("Failed to load files");
}
}
document.getElementById('fileinput').addEventListener('change', readMultipleFiles, false);
</script>
(code from here)
You can find a good explanation and helpful code here.
Thanks to Patrick Hofman's answer, I modified the code and ended up with this :
$(document).ready(function(){
function readMultipleFiles(evt) {
//Retrieve all the files from the FileList object
var files = evt.target.files;
if (files) {
for (var i=0, f; f=files[i]; i++) {
var r = new FileReader();
r.onload = (function(f) {
return function(e) {
var contents = e.target.result;
$('body').append('<h1>' + f.name + '</h1><img src="learn/' + f.name + '"/>');
};
})(f);
r.readAsText(f);
}
} else {
alert("Failed to load files");
}
}
document.getElementById('fileinput').addEventListener('change', readMultipleFiles, false);
});
Is there a way to save the current webpage by using casperjs or phantomjs?
I tried to get the html and save it into a file. But the resulting file was a lot different from the screenshot of that time (with casper.capture). Is there a way to save the current webpage?
Andrey Borisko suggested to use the disk cache to retrieve the resources. My solution is not that efficient, but you don't need to decompress text files.
I use XMLHttpRequest to retrieve all resources after I registered them with the resource.received event handler. I then filter the resources into images, css and fonts. The current limitation is that remote resource paths that contain something like ../ or ./ are not handled correctly.
I retrieve the current page content with getHTML and iterate over all captured resources to replace the path used in the markup, that is identified by a portion of the complete resource URL, with a randomly generated file name. The file extension is created from the content type of the resource. It is converted using mimeType from this gist.
Since CSS files may contain background images or fonts, they have to be processed before saving to disk. The provided loadResource function loads the resource, but does not save it.
Since XMLHttpRequest to download the resources the script has to be invoked with the --web-security=false flag:
casperjs script.js --web-security=false
script.js
var casper = require("casper").create();
var utils = require('utils');
var fs = require('fs');
var mimetype = require('./mimetype'); // URL provided below
var cssResources = [];
var imgResources = [];
var fontResources = [];
var resourceDirectory = "resources";
var debug = false;
fs.removeTree(resourceDirectory);
casper.on("remote.message", function(msg){
this.echo("remote.msg: " + msg);
});
casper.on("resource.error", function(resourceError){
this.echo("res.err: " + JSON.stringify(resourceError));
});
casper.on("page.error", function(pageError){
this.echo("page.err: " + JSON.stringify(pageError));
});
casper.on("downloaded.file", function(targetPath){
if (debug) this.echo("dl.file: " + targetPath);
});
casper.on("resource.received", function(resource){
// don't try to download data:* URI and only use stage == "end"
if (resource.url.indexOf("data:") != 0 && resource.stage == "end") {
if (resource.contentType == "text/css") {
cssResources.push({obj: resource, file: false});
}
if (resource.contentType.indexOf("image/") == 0) {
imgResources.push({obj: resource, file: false});
}
if (resource.contentType.indexOf("application/x-font-") == 0) {
fontResources.push({obj: resource, file: false});
}
}
});
// based on http://docs.casperjs.org/en/latest/modules/casper.html#download
casper.loadResource = function loadResource(url, method, data) {
"use strict";
this.checkStarted();
var cu = require('clientutils').create(utils.mergeObjects({}, this.options));
return cu.decode(this.base64encode(url, method, data));
};
function escapeRegExp(string) {
// from https://stackoverflow.com/a/1144788/1816580
return string.replace(/([.*+?^=!:${}()|\[\]\/\\])/g, "\\$1");
}
function replaceAll(find, replace, str) {
// from https://stackoverflow.com/a/1144788/1816580
return str.replace(find, replace);
}
var wrapFunctions = [
function wrapQuot1(s){
return '"' + s + '"';
},
function wrapQuot2(s){
return "'" + s + "'";
},
function csswrap(s){
return '(' + s + ')';
}
];
function findAndReplace(doc, resources, resourcesReplacer) {
// change page on the fly
resources.forEach(function(resource){
var url = resource.obj.url;
// don't download again
if (!resource.file) {
// set random filename and download it **or** call further processing which in turn will load ans write to disk
resource.file = resourceDirectory+"/"+Math.random().toString(36).slice(2)+"."+mimetype.ext[resource.obj.contentType];
if (typeof resourcesReplacer != "function") {
if (debug) casper.echo("download resource (" + resource.obj.contentType + "): " + url + " to " + resource.file);
casper.download(url, resource.file, "GET");
} else {
resourcesReplacer(resource);
}
}
wrapFunctions.forEach(function(wrap){
// test the resource url (growing from the back) with a string in the document
var lastURL;
var lastRegExp;
var subURL;
// min length is 4 characters
for(var i = 0; i < url.length-5; i++) {
subURL = url.substring(i);
lastRegExp = new RegExp(escapeRegExp(wrap(subURL)), "g");
if (doc.match(lastRegExp)) {
lastURL = subURL;
break;
}
}
if (lastURL) {
if (debug) casper.echo("replace " + lastURL + " with " + resource.file);
doc = replaceAll(lastRegExp, wrap(resource.file), doc);
}
});
});
return doc;
}
function capturePage(){
// remove all <script> and <base> tags
this.evaluate(function(){
Array.prototype.forEach.call(document.querySelectorAll("script"), function(scr){
scr.parentNode.removeChild(scr);
});
Array.prototype.forEach.call(document.querySelectorAll("base"), function(scr){
scr.parentNode.removeChild(scr);
});
});
// TODO: remove all event handlers in html
var page = this.getHTML();
page = findAndReplace(page, imgResources);
page = findAndReplace(page, cssResources, function(cssResource){
var css = casper.loadResource(cssResource.obj.url, "GET");
css = findAndReplace(css, imgResources);
css = findAndReplace(css, fontResources);
fs.write(cssResource.file, css, "wb");
});
fs.write("page.html", page, "wb");
}
casper.start("http://www.themarysue.com/").wait(3000).then(capturePage).run(function(){
this.echo("DONE");
this.exit();
});
The magic happens in findAndReplace. capturePage is completely synchronous so it can be dropped anywhere without much head ache.
URL for mimetype.js
No, I don't think there is an easy way to do this as phantomjs doesn't support rendering pages in mht format (Render as a .mht file #10117). I believe that's what you wanted.
So, it needs some work to accomplish this. I did something similar, but i was doing it the other way around I had a rendered html code that I was rendering into image/pdf through phantomjs. I had to clean the file first and it worked fine for me.
So, what I think you need to do is:
strip all js calls, like script tags or onload attributes, etc..
if you have access from local to the resources like css, images and so on (and you don't need authentication to that domain where you grab the page) than you need to change relative paths of src attributes to absolute to load images/etc.
if you don't have access to the resources when you open the page then I think you need to implement similar script to download those resources at the time phantomjs loads the page and then redirect src attributes to that folder or maybe use data uri.
You might need to change links in css files as well.
This will bring up the images\fonts and styling you are missing currently.
I'm sure there are more points. I'll update the answer if you need more info, once I see my code.
I used the Real Ajax Uploader (http://www.albanx.com/ajaxuploader) for uploading files from my js/jQuery based frontend to an ASP.net based server-side function - that works well by selecting files from the file-system as via the file dialog.
But now i need to find a way to set a file (i know the exact name and local path of the file) to upload automatically via a JS function instead of selecting it manually by clicking "select file" and selecting it from the file-dialog.
I think i have to manually create a file-object and push it into the files array (because of this description to get fiel infos : http://www.albanx.com/ajaxuploader/examples.php?e=6) but I can not manage setting a file and uploading it via my js function
Any help is highly appreciated
Thanks in advance
EDIT:
Thanks for responding Here is the code for taking a picture with the devices camera and pushing it into the files object of the uploader ...
that works so far, but i do not know how to update the fileuploader because it seems not to have a method to do this ...
so the file is in the file-list (file_list[0]) with all the parameters i think it dioes need, but it doesnt show up in the gui-file-list
regards Don
<code>
// photo functions
function getPhoto(){
navigator.camera.getPicture(onPhotoSuccess, onPhotoFail, {
quality: 50,
destinationType: Camera.DestinationType.NATIVE_URI
});
console.log("get photo ...");
}
function onPhotoSuccess(imageURI) {
console.log("photo taken ..." + imageURI);
$('#imgUploadArea').ajaxupload('clear');
var AU = $('#imgUploadArea').data('AU');
var file_list = AU.files; //get all the file objects
console.log("files: " + file_list.length);
// get the file object
window.resolveLocalFileSystemURL(imageURI, function(fileEntry) {
fileEntry.file(function(fileObj)
{
fileuploadShow("input.caseFormText.caseFormPhotoBtn");
// add the image
var capturedImg = new Object();
capturedImg.status = 0;
capturedImg.name = fileEntry.name;
capturedImg.path = fileEntry.fullPath;
capturedImg.size = fileObj.size;
capturedImg.filetype = "image.jpeg";
capturedImg.ext = "jpg";
capturedImg.AU = AU;
capturedImg.file = fileObj;
console.log("set image object to upload: " + capturedImg.path);
file_list.push(capturedImg);
console.log("files: " + file_list.length);
console.log("imgUpload ... imagedata path: " + file_list[0].path);
console.log("imgUpload ... imagedata name: " + file_list[0].name);
console.log("imgUpload ... imagedata status: " + file_list[0].status);
console.log("imgUpload ... imagedata size: " + file_list[0].size);
console.log("imgUpload ... imagedata filetype: " + file_list[0].filetype);
console.log("imgUpload ... imagedata ext: " + file_list[0].ext);
console.log("imgUpload ... imagedata file: " + JSON.stringify(file_list[0].file));
console.log("file added to filelist: " + file_list.length);
var files = $("#imgUploadArea").ajaxupload('getFiles');
console.log(JSON.stringify(files));
//$("#imgUploadArea").ajaxupload.('renderHtml');
//$("#imgUploadArea").ajaxupload('start');
});
});
}
function onPhotoFail(message) {
alert('Photo failed because: ' + message);
}
</code>
Don
I keep on having "ACCESS DENIED" after hitting my download button.
I already have full control on the specified folder.
I use this in jquery.
function DownloadFile(ProductNumber, File)
{
var windowSizeArray = ["width=400,height=400",
"width=500,height=600,scrollbars=yes"];
File = "C:/Documents and Settings/My PC/My Documents/" + File;
if (File != "")
{
var windowName = "popUp";
var windowSize = windowSizeArray[$(this).attr("rel")];
var exist = isExists(File);
if (exist)
{
window.open(File, windowName, windowSize);
}
else
{
ShowAlertMessage("The file for Product no. <a href='" + File + "' target='blank'>" + ProductNumber+ "</a> does not exist.");
}
}
else
{
ShowAlertMessage("No PDF file for Product no: " + ProductNumber+ ".");
}
}
You can't access local files like you do in your snippet.
You have to upload the file to the server and use PHP/another serverside language to do that. jQuery (or Javascript) only runs in the browser and does not have access to files outside it. Serverside web-languages only have access to files located on the server (or other servers using get_file_contents or cURL).
Your code looks like a C#/Java-source. They can access these local files.