I want to read a directory and fill a list with the name of those files.
Is it possible to do this tasks using javascript?
No, for security reasons.
You might be able to do it by invoking ActiveX or Flash and having the user agree to permit file system access from these plugins, but - please don't.
Edit 10 years on:
Not only please don't do this, but now outside of using an old device without updates - you can't do this with Flash/ActiveX.
It's 2022, a lot of changes in the world and beyond, and, lo and behold, now we have something called File System Access API:
This API allows interaction with files on a user's local device, or on
a user-accessible network file system. Core functionality of this API
includes reading files, writing or saving files, and access to
directory structure.
It became available in Chrome 86 (released in October 2020). Safari added support in 15.2 version, released in the end of 2021. To the moment of writing this, Firefox doesn't support this feature though (here's the related discussion).
Also, security considerations didn't go anywhere:
This API opens up potential functionality the web has been lacking.
Still, security has been of utmost concern when designing the API, and
access to file/directory data is disallowed unless the user
specifically permits it.
This part is no longer relevant (kudos to #gignu for mentioning that in the comments) and is left here for historical reasons.
I suppose the closest you might get by using webkitdirectory attribute:
HTML
<input type="file" id="file_input" webkitdirectory="" directory="" />
<div id="list_of_files"></div>
...
JS
var $list = $('#list_of_files');
$('#file_input').change(function(event) {
var listOfFiles = event.target.files;
for (var i = 0, l = listOfFiles.length; i < l; ++i) {
$list.append($('<p>'+ listOfFiles[i].name +'</p>'));
}
});
... as shown here. But it works in Chrome only (and suggested usage of mozdirectory attribute didn't help).
You can try to use FileReader object, but it poorly supported by browsers.
In google chrome you may prompt the client to select a directory and then use this to list the files contained in the directory and its subdirectories:
<input type="file" webkitdirectory onchange="listContents(this.files)">
listContents would be your implementation.
I don't know if you're doing security research etc etc.. So besides from saying "you shouldn't do it", the actual answer to the question is, you can actually READ files by taking advantage poorly-written JS code, that's why you should code.. defensively.
Then there's this: http://www.html5rocks.com/en/tutorials/file/dndfiles/
Yes depending on the browser you have.
Even though it is not a common practice but you can using certain browsers such as Chrome (using the requestFileSystem supported by webkitRequestFileSystem) or in Internet Explorer using File System Object.
Related
I have the following problem:
We are currently using a script to export data from CAD assemblies. This script is running in the Creo browser, which is currently IE. To access the correct directory the following code is used:
var fso = new ActiveXObject("Scripting.FileSystemObject");
var f = fso.CreateTextFile(session.GetCurrentDirectory() + ComponentName + ".xml", true);
f.Write(iht.join("\n"));
f.Close();
The Creo bowser is going to be switched to Chrome. Because of this ActiveX is no longer going to work. Is there a way to archive the same result with different code in Chrome?
Creo is not supporting Chrome Plugins, so IE Tab is not an option.
Any help is greatly appreciated!!
There is a non-standard feature:
https://developer.mozilla.org/en-US/docs/Web/API/FileSystem
But again, it is non-standard.
Edit: as written in that link, "This interface will not grant you access to the users filesystem. Instead you will have a "virtual drive" within the browser sandbox."
No. No more ActiveX.
In the past, most (auto)CAD programs came with a builtin LISP editor you could write scripts in. Maybe that is usable to rewrite the export if you find a LISP programmer.
Myself, I would install node.js on a server so you can use their file system module, which is a good replacement for the old active x object. This probably will require you to copy the files to that server though, so your current workflow might change a bit.
I am using a WebRequest() function within the MetaTrader Terminal 4 codebase (MQL4) that allows one to download a HTML-response from a website.
Example site: http://www.forexfactory.com/docphoenix66#acct.57-tab.list
Here is an example how it is used in the MQL4 function call:
res = WebRequest( "GET",
"http://www.forexfactory.com/docphoenix66#acct.57-tab.list",
cookie,
NULL,
timeout,
post,
0,
result,
headers
);
and the documentation for the function WebRequest()
However, if I compare what is downloaded using a WebRequest() call with what you see when you right click and inspect element using Chrome or Safari, the bits I want available are missing!
In particular I want the trade information from below the following columns:
Instrument Price Open/Close Date Open/Close Lots Return
Profit Pips Chart Balance Swap Duration
And if you see below an example of what is missing from the htm file downloaded using the MQL4 function.
<td class="slidetable__cell slidetable__cell--fixed" style="width: 62px; min-width: 62px;"> <a id="snap_48205_trade_109309333" class="explorer__anchor explorer__anchor--trade"></a>
EUR/USD
</td>
If you download the HTML file, turn off your wifi and then open the file to see what was downloading, you see everything in the trade explorer still loading. Am I clear on what my problem is?
Short version: Yes, there is.
Long version: TL;DR;
Well, first, welcome to the Wild Worlds of MQL4
Given the intention is clear and given you were "promised" that there is "a possible way to read a HTML-page", I have to tell you it is not possible in all cases you will meet in real-world.
One may spend ages in MQL4-code domain to re-design html-sort-of Mark-Up syntax-(b)LOBs, suffering from all the restricted constraints the MQL4-code execution engine provided.
Nevertheless, the much faster, joyfull and a sure and future-proof ( read other posts on historically painfull creeping of the language syntax relief and crippled man*decades in API-integration code-base efforts ) approach exists .
Integrate MQL4-side via a professional fast & low-latency SIG/MSG-infrastructure with external, distributed processes, that can provide high-performance & robust services to MetaTrader Terminal ecosystem.
Using this approach we have prototyped and operate fast Mixed-Technical-and-Fundamental AI/ML-Inputs, including Web-page-feeds of Fundamental Data and News Announcements into the FX-trading realm 24/7/365 and it works blessingly well, independently of the limits the common MQL4 execution has.
If still in doubts, just try to read a page on rss.provider.com:6322/FED_actuals URL via a call to WebReqest() and you know, where is the dog burried.
I am currently working on a web media player and would like to use the new "Folder Upload API" from Google Chrome (or however its being called officially) to recursively work with local directories. Unfortunately I wasn't able to find any further information on this and I'm not quite familiar with HTML5's FileReader object. Is there any official site or documentation of that specific API by any chance?
Without posting the entire and minor code of my example, I would like to refer to a JSFiddle site: http://jsfiddle.net/a869q/
The example displays both, the 'usual' upload method and the one using webkit-directory.
<input id="file_input" type="file" multiple="" />
<input id="file_input_dir" type="file" multiple="" webkitdirectory="" directory="" />
<div id="test"></div>
On event.change the references (blobs) to these files are then being used to get duration of mp3-files and to create a list of audio-elements. Works just fine. Choosing directories only works in Chrome.
$('#file_input, #file_input_dir').change(function(e) {
$.each(e.target.files, function(index,file) {
// ....
$('#test').append('<audio src="'+window.URL.createObjectURL(file)+'"></audio>');
// ....
});
});
Now, using Javascript / jQuery I would like to find out if the client does support the new webkit-directory feature and I really hope that there is a way doing this without just reading the UserAgent and check against string "Chrome". Any ideas?
Regarding the matter, that it's only working in Chrome at the moment, I would also like to know if there is a common or suitable workaround to let this work in different browsers, but at least Firefox. In this article there have been some neat posts made with different examples already. But mainly all the working plugins are using Flash or Applets which I'm really trying to avoid. Still hoping for solution.
In addition, talking about the method I'm gathering the duration of chosen audio-files with (please see JSFiddle). Any way doing this with pure JScript, without creating HTML5-Audio-Elements?
(function() {
var input = document.createElement("input");
input.type = "file";
return !!("webkitdirectory" in (input || document.querySelectorAll("input[type=file]")[0] ))
}())
if (window.ActiveXObject) {
try {
var fso = new ActiveXObject("Scripting.FileSystemObject");
fso.CopyFile("C:\\Program Files\\GM4IE\\scripts\\source.txt","C:\\Program Files\\GM4IE\\scripts\\target.txt", 1);
fso = null;
}
catch (e) {
alert (e.message);
}
}
I am getting error :
"Automation server can not create object" on the line where I am creating ActiveXObject instance.
I understand that it's considered very bad to access hard-drive data using javascript but I just need it.
I am using IE8 , Greasemonkey4IE to run my javascript.
Thank you,
Mohit
******************************
function WriteFile()
{
var fso = new ActiveXObject("Scripting.FileSystemObject");
fso.CopyFile("C:\\source.txt","C:\\target.txt", 1);
}
I've put the above code inside a simple HTML page and it worked perfect.
http://www.c-point.com/JavaScript/articles/file_access_with_JavaScript.htm
You can find the similar code on above mentioned location.
I modified it a bit, tough.
But when I am trying to run it through GreaseMonkey4IE it simply spitting the same error I specified earlier.
I did it guys, but thanks a lot for your quick and helpful replies.
All I did is :
Go to Tools > Internet options > Security > Custom Level
Under the ActiveX controls and plug-ins, select Enable for Initializing and Script ActiveX controls not marked as safe.
Using native JavaScript, no, it is not generally possible to access a local file. Using plugins and extensions like ActiveX, Flash, or Java you can get around this rule, generally with some difficulty.
For some browser and OS specific exceptions to this general rule, you might want to have a look here:
Local file access with javascript
Note that as of late 2012, the FileReader API has been supported in all major browsers and provides a native JavaScript mechanism for accessing local files that the user nominates (via an input element or by dropping them into the browser).
This still cannot be used to access an arbitrary file by name/path as in the examples in the original question.
HTML5 File API has multiple ways to access local files.
window.requestFileSystem allows you to request access to the filesystem. Browser support is very poor on this (Chrome only).
FileReader is the HTML5 FileReader API that allows you to programatically read files that users select through a <input type='file' /> Browser support is better on this.
You should use fallbacks like flash and POST to a server for full file access.
Generally reading arbitary files is considered "cheating the browser" so I you'll either have to use secure HTML5, ActiveX or Flash. All 3 of those require user permissions.
After some research I have found:
var fso = new ActiveXObject("Scripting.FileSystemObject");
//This line will create a xml file on local disk, C drive
fh = fso.CreateTextFile( "C:\\fileName.xml", true);
fh.WriteLine("this is going to be written in fileName.xml");
This is how we can do it.There are other methods also.
Accessing local file system is very bad thing to do but yes we can do it.
Automation server can not create object
To get rid of this error go to Tools → Internet Options → Security → select Internet icon → click Custom level → select Enable for Initialize and script ActiveX controls not marked as safe for scripting.
I have not tested this on any other berowser except IE8, but I am sure it will work.
I've got a javascript file that uses
excel = GetObject("", "Excel.Application");
to hook a current running instance of excel, however it requires me to drop my security settings super low. How do I go about code-signing a javascript file to at least cause a security prompt instead of just failing? Google-ing keeps getting me results for signing custom activex controls, .dlls, and .exes but all I need is the built-in function approved.
On a related note
http://msdn.microsoft.com/en-us/library/7tf9xwsc%28v=vs.94%29.aspx
"The GetObject function is not supported in Internet Explorer 9 standards mode or later."
What is the proper method for accessing a currently running application in IE9 then?
There is no way to do that; there's no "code signing" mechanism for JavaScript.