I'm working on a Silverlight control that will allow multi-file downloading. At the moment I'm trying to get my mind around the permission model of the browser.
Let's say, on a web page, a user enters a local folder (c:\temp) in a text box. The user then clicks a button.
Is it possible in JavaScript or Silverlight, to write a collection of files (that are stored on the server) to that folder on the user's drive?
From Javascript - NO. It would be way too easy from some scumbag to install a virus on your PC if that were possible.
Silverlight I don't know about, but I would assume writing to the users hard drive would be very limited and tightly controlled.
Only if the browser has a security hole that you can exploit.
Since the capability you describe would allow any webpage to do whatever it damn well pleases to the visitor's system, there is no way anyone would implement arbitrary access to the local disk deliberately in this day and age.
The next best thing you can to is to have the user download a ZIP archive and tell him to decompress him wherever he likes.
You cannot from Silverlight. The only thing you have access to is the Isolated Storage.
http://blog.paranoidferret.com/index.php/2007/10/12/silverlight-tutorial-using-isolated-storage/
http://msdn.microsoft.com/en-us/library/bdts8hk0.aspx
Warning: most of these answers are incorrect.
You can so write to a file via Javascript in both MSIE (using ActiveX FileSystemObject) and Firefox (using nsIFileOutputStream). In both cases the user will be presented with a security dialogue, which can be allow or deny the read or write.
I have used the Scripting.FileSystemObject to do this. Only works in IE, and only with very relaxed and unsafe security settings, but it might work for intranet sites in an enterprise, at least it worked for me.
Google Gears has a method to do client-side storage.
http://gears.google.com/
That said, I doubt it will do what you are attempting. I think you would be better off having a server-side thing download files and put them into a .zip file for the client before passing it on to them.
As it was answered earlier, this would have to be done via server-side, Silverlight and JavaScript are sandboxed to disable this type of security hole. I would suggest packing the files into a zip archive on the server and then downloading the zip archive.
You can do this via an ActiveX control or Java applet. Either way you do this the project has to be signed with a code signing certificate. You can use a self-signed certificate but the warning dialogs will be louder and brighter.
You can then use Javascript to call into the signed control and save files. Be very careful about creating an applet like this. You don't want to allow any other website to use this control so the control must implement some of the following:
Only work on a certain website.
Save files only in a specific location.
Prompt the user where to save the files so that they know that this is happening and it doesn't happen silently in the background.
You can probably find a control or applet somewhere that can be controlled with Javascript.
I don't believe this is possible as it create countless security problems. The only way I can see this being secure is a mix of user permissions and some way of verifying (on the client side) the authenticity of the website and the files they want to download to my computer.
One method you could do is triggering the "FileSaveDialog" but I don't think that is what your looking for. Maybe packaging the collection of files first and then triggering is the way to achieve your goals. Silverlight only allows for 1mb of isolated storage per domain and will absolutely not give sites access to the clients hard drive.
This doesn't directly answer the question, but Adobe Flex 4 allows doing it with FileReference class.
Silverlight 4 OOB allows access to the user's document directory.
Related
I've found a question or two regarding accessing the built-in Windows Certificate viewer using a .NET framework.
I'm wondering, however, if there's a way to display a certificate's information using the Windows Certificate viewer via JavaScript. I have a page on which a user can drop/upload a local file, and then the JavaScript code extracts the certificate information stored in this file. I would love to be able to pump that directly into the Windows Certificate viewer to give the user a familiar interface to work with.
Is this possible with plain 'ol JavaScript? I don't have access to many non-standard libraries.
The page doesn't need to store anything or upload any information anywhere; it is simply supposed to give information about the given file and its contained certificate data.
Taylor, no there is no access to the local certificate store from Javascript. This would be a violation of the browsers same-origin security policy.
Your only choice to do this would be to use a Java applet, browser plug-in or COM control to escape the sandbox.
Depending on what you want to do it might be viable to stay in the sandbox and use something like https://pkijs.org.
Otherwise I think your out of luck.
We are currently looking at porting a enterprise silverlight application over to html5. The major roadblock that we have hit is the ability to open files from the user's local disk. Currently they have a document library which just links to files on their computer that they can open from within the app and view or print out. All that I read is that you can only access the local sandbox of the web app with the html5 file api's. We want to load these files from code.
Does anyone know of any workarounds to this?
Thanks
There is no way for html5 to access local file without user selection. But FSO: FileSystemObject works for IE and MAYBE could be regarded as a work around. But still there are some requirements to meet.
It is possible to use chrome's filesystem API to access files on a users local filesytem. So you'd have to be willing to make this a chrome only application.
Using java you can create a "Signed" applet which has access to the local filesystem. (if the applet is signed you can request filesystm permissions)
then there is a tutorial for accessing methods of your java code directly from javascript here: http://docs.oracle.com/javase/tutorial/deployment/applet/invokingAppletMethodsFromJavaScript.html
you should be able to perform something similar from silverlight.
There is no workaround in pure HTML5/Javascript. You need the use of plugins, such as Java or Silverlight (maybe you shouldn't port it after all). As for workarounds, HTML5 gives you an easy way drag and drop multiple files that you could transfer on the server and then display back to your users. Another workaround would be to install a custom agent (a software with only a tray icon) that would send the information about the current user "document library" to server and then again, you could display it back to the user.
Note: I've heard somewhere that browsers will eventually stop supporting plugins. http://www.howtogeek.com/179213/why-browser-plug-ins-are-going-away-and-whats-replacing-them/
Ya, I agree with Markain. However, if you were to limit your audience solely to chrome users, I daresay, you would most likely use some of your users. If Huazhihao is right, then your number of leaving customers should decrease but users who regularly use firefox won't be happy. Overall, I think that this will not work. Otherwise, there would be too many websites that trashed your hard driver (or at least wherever you have the rights to edit/delete files). I think it would be best if your product was setup to synchronize the file whenever an internet connection was detected and a change was made to the file. That way the user would not need to visit the website whenever the file was uploaded. If this is some kind of an error file, then it would be most beneficial if you were to make a link in the application that when clicked, would upload the file to the website and the website were to do whatever was necessary. If this is a purely online thing, then I don't see what business you would have looking through other peoples' files =-). Hope I helped!
I am all too aware of the fact that even with the new FileAPI it's not possible to access the local path of a file added using a file input field or drag-and-drop. Whether or not this is good, bad or ugly is not the issue here. According to the FileAPI specs local file access is not to be implemented, and so I'm not holding my breath.
But let's just pretend I'm in a situation with the following fixed parameters:
Developing an HTML5 application only to be used internally at a company
.NET used for backend (needed due to interop with APIs)
Can specify/control exactly which browser and version should be used with the application
Need to access files that are usually located on a network share, but possibly also locally at a user's workstation
And by access I don't mean access file data, but rather be able to relay a file drag-and-drop/select event to some other API by feeding the third party the file's local path, so that the third party can pick up the file and do some sort of work on it. This can be likened to using an input[type=file] field as you would an OpenFileDialog in .NET - i.e. the point is to feed the application a file path, not an actual file.
I realise that out of the box this is probably not possible. But I also think that there must be some sort of solution to the problem.
Some ideas I've been toying with are:
Using browser specific methods for allowing "secure features"
Not sure if possible - tired using some of these features to no avail
Would limit the app to a specific version of a browser as the functionality could potentially be removed in the future
Something like a Chrome extension could possibly do the trick
Using some sort of companion application installed locally on a clients computer that takes care of all on-disk file handling, possibly communicating with the HTML5 client using websockets or the like.
A potentially pretty messy solution
Would probably confuse the users a bit at first
Submitting the selected file data to the server, storing it at specific path and sending this new path to the third party.
Would constitute a lot of sending files over the company network, some 100+ MB in size
Would not be able to do any in-place changes to a file a user has selected
... and that's about it.
Any snazzy suggestions? Wise words? Helpful links? Snarky comments?
Thanks.
Edit: For anyone curious about it, this was very simple using Silverlight as per jgauffin's suggestion below.
From the Silverlight codebehind (using elevated privileges):
private void fileBtn_Click(object sender, RoutedEventArgs e)
{
//prompt file select dialog in Silverlight:
var dlg = new OpenFileDialog();
dlg.ShowDialog();
//call JavaScript method and feed it the file path:
HtmlPage.Window.Invoke("onFileSelected", dlg.File.FullName);
}
You'll probably have to use something that runs in the browser like flash or silverlight.
Since it's an internal app I would use silverlight as everything else is in .NET. It should be enought to only make the file access part in the plugin.
Here is an article about local file access: https://www.wintellect.com/silverlight-4-s-new-local-file-system-support/
does the server hosting the site have access to the network of pc's?
you could just list all the files that way.. build a small ajax script like a file dialog that will have php or whatever sending back the structure
no plugins needed, works on all browsers... :)
I'm developing a web app that needs some sort of filesystem access. Ideally I'd want to be able to "Open..." a file into the app and then "Save" the file back to local filesystem at the location that the user opened it from.
Currently, we use a java applet to achieve this functionality, but since java is going out of style, we're needing to do this with javascript and html5.
Obviously, this can't be done because of security reasons built into browsers, so I'm trying to somewhat emulate it.
I'm using the html5 file api to successfully import/open the files, so that's half the battle. The hard part is getting the saving feature. I'm getting close using an iframe and content-disposition, but problems arise when browsers are set to automatically download the files to a downloads folder... users may get confused and be unable to locate the file they just downloaded.
So, my question is this: is there some sort of onSave event or some kind of way for the browser's "Save As..." window to return at least the filename that the user saved the file under?
Also, I've looked into the filesystem/fileWriter html5 apis, but from my understanding they're limited to only a sandboxed area of the local filesystem and only available in chrome dev releases.
Any help would be appreciated!
No, there is no way to do that with pure JavaScript. You can manage to trigger a download with data URIs or an iframe with some headers but you can't circumvent the browsers' download managers.
You can either use a Flash or Java applet to handle the saving for you, or ask the user to right click on the link and do save as, then he might be able to choose the destination.
One popular option using Flash is Downloadify.
I have a couple of solutions, but none of them work perfectly.
Platform
ASP.NET / VB.NET / .NET 2.0
IIS 6
IE6 (primarily), with some IE7; Firefox not necessary, but useful
Allowed 3rd Party Options
Flash
ActiveX (would like to avoid)
Java (would like to avoid)
Current Attempts
Gmail Style: You can use javascript to add new Upload elements (input type='file'), then upload them all at once with the click of a button. This works, but still requires a lot of clicks. (I was able to use an invisible ActiveX control to detect things like File Size, which would be useful.)
Flash Uploader: I discovered a couple of Flash Upload controls that use a 1x1 flash file to act as the uploader, callable by javascript. (One such control is FancyUpload, another is Dojo's Multiple File Uploader, yet another is one by darick_c at CodeProject.) These excited me, but I quickly ran into two issues:
Flash 10 will break the functionality that is used to call the multiple file upload dialogue box. The workaround is to use a transparent flash frame, or just use a flash button to call the dialogue box. That's not a huge deal.
The integrated windows authentication used on our intranet is not used when the Flash file attempts to upload the files, prompting the user for credentials. The workaround for this is to use cookieless sessions, which would be a nightmare for our project due to several other reasons.
Java Uploader: I noticed several Java-based multiple-file uploaders, but most of the appear to cost money. If I found one that worked really well, I could arrange to purchase it. I'd just rather not. I also don't like the look of most of them. I liked FancyUpload because it interacted with html/javascript so that I could easily style and manage it any way I want.
ActiveX Uploader: I found an ActiveX solution as well. It appears that ActiveX will work. I would just write my own instead of buying that one. This will be my last resort, I think.
Resolution
I would love to be able to use something like FancyUpload. If I can just get by the credentials prompt some way, it would be perfect. But, from my research, it appears that the only real workaround is cookieless sessions, which I just can't do.
So, the question is: Is there a way to resolve the issues presented above OR is there a different solution that I have not listed which accomplishes the same goal?
I don't think there is any work around for the integrated windows authentication. What you could possibly do is save the files to a generic unprotected folder and, in the case of swfupload, use a handler to move the file when its fully uploaded
You could try SWFUpload as well - it would fit in your Flash Uploader "category".
Our company uses https://ajaxuploader.com which supports this feature.
In Internet Explorer, FileReference.upload (flash upload) will send cookies along as well.
This behavior breaks only when running in other browsers.
#davidinbcn.myopenid.co: That's basically how I solved this issue. But, in an effort to provide a more detailed answer, I'm posting my solution here.
The Solution!
Create two web applications, or websites, or whatever.
Application A is a simple web application. The purpose of this application is to receive file uploads and save them to the proper place. Set this up as an anonymous access allowed. Then make a single ASPX page that accepts posted files and saves them to a given location. (I'm doing this on an intranet. Internet sites may be exposing themselves to security issues by doing this. Take extra precautions if that is the case.) The code behind for this page would look something like this:
Dim uploads As HttpFileCollection = HttpContext.Current.Request.Files
If uploads.Count > 0 Then
UploadFiles(uploads)
Else
result = "error"
err = "File Not Uploaded"
End If
Application B is your primary site that will allow file uploads. Set this up as an authenticated web application that does not allow anonymous access. Then, place the FancyUpload (or similar solution) on a page on this site. Configure it to post its files to Application A's upload ASPX page.