Use an existing local file without the need to choose - javascript

I have developed a script for myself to read and process local text and csv files on my computer using recent Chrome or Firefox browsers with the filereader api. The script will work on the computer, even though it is not connected to the internet or a local webserver.
The reasoning behind this is to have a standalone text file interrogator, which will work on almost any computer, requiring only a browser to execute and display reasonably formatted output. similar to an awk type application.
I use the filereader api and it works well.
I do not properly understand the workings of the browser, so my question may be very stupid.
Is it possible that my script can somehow pass the filename to the script filereader api, without having to choose a file from input type=file field.
eg I have a file called addresses.csv and it resides in the same directory as my html/js file with the filereader api code.
I want to simulate the choosing of a file, without accessing my local directory and without using a webserver, but a dropdown box of predefined filenames would be even better.

No, for security reasons its not possible, because otherwise people could open arbitrary files on the computers of their visitors which is definitely not intended.
This specification also assumes that the primary user interaction is with the element of HTML forms [HTML], and that all files that are being read by FileReader objects have first been selected by the user.
See http://www.w3.org/TR/FileAPI/#security-discussion

No you cannot. Javascript cannot read your local filesystem without the use of a file input or drag and drop files (html5) as it would be vulnerable to malicious use.
There was a start of a filesystem api which Chrome has included. But you cannot read/write to just any place you want on the filesystem, you can only do so to a sandboxed area on the filesystem. Wither or not they will continue to have this in future versions of Chrome though I do not know.
It also appears the W3C itself has discontinued the file system api

Related

How can I get the current Excel file in Office JavaScript API?

I am developing a tab pane app in Excel which needs to read the current document. In Word, the Office JavaScript API has the method Office.context.document.getFileAsync(), but this is not available in Excel.
I can get the URL of the document with Office.context.document.getFileProperties(), and then I thought I could read the file with this.
I tried using the HTML5 FileReader() object, but this only works for files selected from the file input control. I tried manipulating a hidden file input control so it automatically uses the current document, but JavaScript understandably prevents you from doing this for security reasons. I could ask the user to browse to the document they are currently using but that would be a poor user experience.
So I tried using ActiveXObject('Scripting.FileSystemObject') but ActiveX is not allowed in tab pane apps at all, whatever the current security setting are in IE.
What other options do I have?
According to the API road map, Office.context.document.getFileAsync() is not available in Excel at this moment.
I don't think it's feasible by using getFilePropertiesAsync(). It only returns the URL. Usually browser forbids developer touching any content in the file system. Therefore, it's hard to access the local file system in JavaScript code.
Besides, the file may not be in local file system. For example, it could be hosted in Onedrive or SharePoint. getFilePropertiesAsync() should return its real URL in Onedrive/SharePoint, instead of local file system.
I guess Microsoft will support getFileAsync() in the future.

How can a Chrome extension save many files to a user-specified directory?

I'm working on a Chrome extension to be used as an internal tool. Its required behavior is:
As a page action, enable an address bar icon when looking at certain intranet pages.
when the user clicks the icon, identify all files of a certain media type (say, .jpg) on the page, and
silently save them all to a directory on the user's local drive.
This question has been asked before, but the answer then was "use NPAPI", and NPAPI is now derelict.
So, what is the currently available way to achieve this? The ones I've looked at are:
The chrome.FileSystem API --- but this does not save files in any user-accessible location. Instead the stored files are hidden behind obfuscated names in an undocumented directory. User requires that the files be stored under their original names in an accessible directory.
The HTML5 download attribute, by creating a data: URL and programmatically clicking it. This pops up a "save as..." dialog for each file, which is unacceptable when there are a hundred assets on a single page. User requires that the files be downloaded without further interaction beyond the single icon click.
The Chrome Download API, but that is only available in the beta and dev channels. User requires this extension work with mainstream Chrome.
Use the Native Messaging API by creating a small .exe that simply saves a file to disk, and then pass the .jpg as a blob to it. This seems very cumbersome and I am not even sure how to reliably pass large blobs to EXEs like that.
Is there another approach I can try?
You've done quite a lot of research. Indeed, regular web pages cannot write to the user's filesystem without any plugins or extensions. Also, the HTML5 Filesystem API only provides access to a virtual filesystem, as you've observed.
However, you are confusing the chrome.fileSystem API with the HTML5 FileSystem API. Unlike the HTML FileSystem API, Chrome's fileSystem (app) API can directly write to the user's filesystem (e.g. ~/Documents or %USERPROFILE%\Documents), specified by the user.
This API is only available to Chrome apps, not extensions. This is not a problem, especially since you're developing an internal tool, because you can install the app and extension, and use message passing to communicate between the extension (page action) and app (file system access) (example).
About chrome.downloads: Since your extension is internal, you can probably force users to get on the beta/dev channel in order to use this API. The only limitation of this API is that the files will be saved in (a subdirectory of) the user-defined Downloads folder.
EDIT: The chrome.downloads API is now avaiable in all channels, including the stable branch (since Chrome 31).
I am afraid that you have done your homework, meaning you looked at all possible alternatives.
The best way to achieve exactly what you want, would be (as you mentioned) using a supporting native app and communicating through Native Messaging. BTW, since bandwidth is rarely a problem on intranets, you might find it simpler to pass the resources (e.g. images) URLs and have the app download and save them.
(Yes, it will be more cumbersome than simply developing an extension, but one's got to do what they've got to do, right ?)
On the other hand, if you are willing to sacrifice a little bit of user's experience over simplicity of development, I suggest combining the HTML5 goodies (that allow you to create and download a file locally) with a JS zipping library (e.g. JSZip), so the user only has to download a single zip file (and is only prompted once). BTW, if the user wishes, he/she can choose to always download the files without prompting (but you knew that already).
Use the Native Messaging App idea.
The native app is cumbersome and a pain to write because documentation is poor, and unless you get the JSON formatting exactly correct on both ends you will not see anything in a console because stdin and stdout are taken over.
But, you will be happier when it is done because you can use standard tools (e.g., Windows Explorer, a hex editor, TeamViewer...) to view, move, and delete files, and otherwise see what is going on. Chrome's sand-boxed file system works, but seems to now be a dead-end (no other browsers have picked it up). No one is likely to develop third-party tools for it. Of course you probably don't need tools once everything is working, but until then, debugging is a nightmare because you need to write code (and quite a lot of code) just to track what files are in what directories, file versions, remaining disk space...
Another solution for internal (or may be non-internal) usage is to connect to a websocket server, local or remote.
You can put it in both background.js or content.js (use wss:// for https://)
var ws = new WebSocket('ws://echo.websocket.org');
// var ws = new WebSocket('ws://127.0.0.1:9000');
ws.onmessage = function(res) {
console.log('received data:', res.data);
};
ws.onopen = function() {
ws.send('hello');
};

An alternative to input type="file" to read a file in javascript

I am wondering if there is any method of reading file on the client side with javascript given the file name and path. I am aware of the method of reading through: input type="file".
What I mean is without opening up a file browser and selecting the file, just reading it with filename, like fopen.
If not an other method, how to instantiate a File object in javascript from filename and path?
Seeing the answers I thought of briefing a bit more on my purpose.
I am not really making a webpage. I am using browser just as a software that is available on any system. The html pages will all be local. I am doing this way be so that I have the advantage of the power of js. Given this situation is there any way to set permission flags that will let it read files?
Thank you.
There's the Drag 'n Drop API which would be the other option in reading files using JS
There will always be hurdles so that your code will not directly read from the client's filesystem. This is designed for privacy and security purposes.
Extensions/Plugins - sandboxing will be your enemy, limiting file system access
Java Applet - Needs a signed certificate to read the filesystem. A self-signed certificate will generate the "Will You Trust This Applet" prompt which would act as the security prompt.
Input type=file - gives the user the option to select the files or not
drag and drop - gives the user the option to drag in files or not
XHR - Same Origin Policy will block you, especially if you are executing the page locally and not on a server.
JSONP - Since this bypasses the SOP, however, your file should be in JSONP format.
I found solution to my problem, here it is...
It is true that we have restriction with javascript that whenever the user or the page requests for a file it has to go through that extra window that pops up,
but if all the files that you may request are inside a known folder then you can rather ask the user to point the zipped folder instead.
One can use tools like zip.js for opening a file that one needs in the zipped folder.
Thank you :)

JavaScript read file contents

how can you retrieve the data from a document with javascript that isn't the page you are on if you have the url of the new document.
what i am trying to do is create a page that has a text field for providing a local file name and a button that retrieves the words from the document provided.
thanks.
HTML5 has a File API that lets you read local files. It's supported in at least Firefox (3.6 and later, I think) and Chrome. I don't know if any other browsers support it yet or not. If you need to support other browsers, you'll have to fall back to something like Flash, but I don't have any experience with that.
Unfortunately, by default Chrome doesn't allow local files to access other local files (each file is considered to be from its own domain). You can explicitly allow it by adding the --allow-file-access-from-files flag when you launch Chrome.
Here's a good introduction to the File API with several examples: http://www.html5rocks.com/en/tutorials/file/dndfiles/.
Browser security does not allow direct access to the local filesystem. If it could, web pages would be able to steal any file of your machine.
HTML5 local storage does allow local access, but on a different principle.

Is it possible to upload and extract a zip file to a given location using only HTML and JavaScript?

I have a web page which asks users to select a zip file on their machine and upload it. It also asks for a destination on the server where the zip file should go. I want it to work in such a way that when they tell me where the file is on their machine and where it belongs on my server, then click "send," it should be sent to my server, placed in the designated directory, and unzipped.
I want to do this in just HTML and JavaScript. Is that possible? If so, how would I go about doing it?
You have to do this serverside; the client's browser cannot write to the file system of the server directly as it's a huge security risk.
In addition to that, not even HTML5 with it's File API can extract ZIP files. You need to do it on the server with PHP, or whatever language you're using.
If you just want to do things locally on the client, you could consider a Flash/Java/Browser extension, but I wouldn't recommend it for compatibility and performance reasons. Your best bet is to send a request to the server for it to process and send back. You're already serving the HTML page, so you can use the same server to process the ZIP file.
If, on the other hand, you want to write the ZIP file to the server, you have to do it server side for reasons stated in my first paragraph.
You can unzip/zip content within JavaScript using rawdeflate.
As other posters suggest, you cannot save directly to the local filesystem using a plain browser. You either need to echo the result back off the server (in which case it may as well unzip), or you can use Flash, for example, Downloadify, if it is installed.
Most modern browsers support FileAPI for loading from the local filesystem, certainly, Chrome, Firefox and Opera do. I haven't tested IE 9.

Categories

Resources