Migrating to Edge Browser - file upload not working - javascript

We are migrating from IE 8 to Edge browser,
Below is the code working in IE 8, to load one file, but not in Edge.
if(window.ActiveXObject){
var fso = new ActiveXObject("Scripting.FileSystemObject");
var filepath = document.getElementById('filePath').value;
var thefile = fso.getFile(filepath);
Could you please let me know equivalent code for edge browser.

Edge doesn't support ActiveX. You can use File API <input type="file"> to choose files and then use XMLHttpRequest to upload files in modern browsers.
For more information you can refer to this thread and this code sample.

A lot has changed since the code you are trying to upgrade was created. Local Storage now exists and to download a file; (Use case somebody may need to save it for using it locally) a download attrib is added to the anchor html tag. The file needs to be made into a URL-Blob
<a id="download" download="example.png">
<button type="button" onClick="download()" class="UI">Download</button>
</a>
<script>
function download() {
var download = document.getElementById("download");
var image = document.getElementById("meme").toDataURL("image/png").replace("image/png", "image/octet-stream");
download.setAttribute("href", image);
}
</script>
I would migrate to local-storage or IndexedDB API.
There is no drop in replacement for the activeX. because of security issues.
Major Differences
ActiveX allowed javascript to access a file to read or write, including being able to overwrite itself, anywhere on the hard drive.
HTML5 Allows reading and writting to localdata and several API for data including IndexDB. But file access is limited to what the user specifically uploads or for downloading into the download directory.
A Javascript WIKI page that replaces itself is no longer possible if you want it to overwrite itself. A Javascript WIKI page is possible using the IndexDB. Downloading the content is possible but limited for security reasons.

Related

Copy/download temporary files

I am not an HTML/JavaScript developer. I am having to modify some legacy code written by someone who has left.
We have a Python app which acts as a local server with an HTML/JavaScript front end that can be viewed in a browser.
The Python creates a temporary cache file. I would like to give the user the option to save a copy of this temp file to a location of their choice or at least download it to the downloads directory (Windows & Linux)
I've tried adapting some of the ideas from here: https://www.delftstack.com/howto/javascript/javascript-download/
E.g.
const saveAnalysisBtn = document.getElementById("saveAnalysisBtn");
saveAnalysisBtn.addEventListener('click', saveAnalysis);
function saveAnalysis(evt) {
function download(filename) {
var element = document.createElement('a');
// hardcode temp file name just for POC
element.setAttribute('href','file://C:\\tmp\\my_temp_cache.db');
element.setAttribute('download', filename);
document.body.appendChild(element);
element.click();
//document.body.removeChild(element);
}
var filename = "output.txt";
console.log(`Call Download`);
download(filename);
}
In Firefox this gives a security error:
Security Error: Content at
http://127.0.0.1:5000/replay/fapi_15_6_udi.bin may not load or link to
file:///C:/tmp/my_temp_cache.db
Which isn't terribly surprising. (Edge & Chrome give similar errors)
Is there a way to do this? Can be in HTML or JavaScript or Python (though I would like user to see evidence of download taking place in the browser).
Maybe I'm not understanding, but it looks like we're talking about just copying a file from one local location to a user specified location. The file you want to copy is on the machine the user is using? Couldn't you just provide the location in the web page and then just go there in a file explorer, finder, or command line tool to copy it however you want? It would solve the security issue.
But if you're required to create a link, you could create a download process that zips the file up to make a file like "my_temp_cache_db.zip" (or whatever compression tool/extension works best for you), and then provide the link for that. Zip files work through browsers better than some other types of files, and the user just has to unzip it wherever it ended up.
If that's not ideal, you could create a download process that makes a copy of the file and just changes the extension to something like "txt". The user downloads that file and then has to rename it to have the right extension.

How to store and load/display local PDFs with browser-data, from a website

I'm working with an extremely old database system containing people and associated PDFs. I can access most data over a webbrowser, however PDFs cannot be requested via web-api - I do however have the liberty of loading any javascript library, and use chrome webdev console.
I want to get a proof of principle working, where I can load a person's PDFs. But I'm not quite sure what the best approach is.
Idea to upload a file to the website's local storage in my browser (since it's viewed several times). However I seem to be lacking a good library to save/load files from the cache directory. This library wasn't updated since 2016 and Filesaver.js doens't seem to be keen on loading the files after saving. Using a fully-fledged database implementation seems overkill (most files will be <= 5-10MB)
Loading a file from local storage (even if dir is added to workspace in chrome) seems completely impossible, that would've been an alternative
adding the local file path to a <a href=""> element did not work in chrome
Is there a feasible approach to manage/associate PDF files on my local drive with the website I'm working with (and have full client-side control, i.e. can load any library)?
Note: Access is restricted, no chrome addons can be used and chrome cannot be started using custom flags
I don't exactly know what you are asking for, but this code will get all the pdfs in a selected directory and display them and also makes a list of all the file objects. This will only work in a "secure context" and on chrome
(it also wont run in a sandbox like a stackoverflow code snippet)
js
let files = [];
async function r() {
for await (const [_, h] of (await window.showDirectoryPicker()).entries()) files.push(await h.getFile());
files = files.filter(f => f.type === "application/pdf");
for (const f of files) {
let e = document.createElement("embed");
e.src = URL.createObjectURL(f), e.type = f.type;
document.body.appendChild(e);
}
}
html
<button onclick="r()">read PDFs</button>
also you can probably use this if you need to send the local PDF somewhere
not sure this answers the question but i hope it helps
Since ActiveX controls are no longer available browsers can display a PDF or a user can download the pdf.
For any more control over that I suspect you could try render the pdf using a JavaScript library like https://mozilla.github.io/pdf.js/
For full control you wont be in a position to control the PDF version, you could alternatively render the PDFs to images on the server and display image versions of the pages.

Download a file by changing window.location w/ Safari

I have an offline html file that generates and saves a CSV by setting window.location to
data:text/csv;base64,Intfa2V5fSIsInt...
However, in Safari this just brings up the CSV in the browser.
Setting the url to:
data:application/csv;base64,Intfa2V5fSIsInt...
forces Safari to download the file - but it gets a generic file name of just 'Unknown-3'. Is there a way to specify the file name?
First, a warning:application/csv isn't a valid MIME type, so the fact that it "works" for you in this case is purely an implementation quirk that could very well change in the future. (For example, Safari displays application/octet-stream, which I'd expect to download.)
HTML5 does have a new <a download="file.name"> attribute. This forces the browser to download the file to disk; it uses the attribute's value as the default file name. It does work in conjunction with a data URI or a blob URI. (Demo)
However, it is currently only supported by Chrome (14+). Safari 5.1 ignores the attribute.
A possible alternative is to use the Filesystem API, but that gives you a sandboxed folder to work with. You can't—for example—save a file directly to the user's Documents folder. Instead, you can write a file to the sandbox and then redirect to file on the new filesystem schema:
location.assign('filesystem:http://example.com/temporary/somefile.csv');
This should invoke the UA's download mechanism (with the right filename!), but I haven't tested this, so it is possible Safari will just display the file anyway.
According to the RFC 2397 no. There is no way.
Also read this related question.

Save XML file on my machine with XMLDom object save()

I'm not able to save to the xml file on my machine.
I have noticed that node value is changed temprorily but not permanent in xml file.
P.S : This is only a simple HTML file with javascript
It is giving me an error "Permission Denied"
function viewBookDetails() {
var xmlDoc = xmlLoader("cart.xml");
//var x = xmlDoc.getElementsByTagName("dogHouse")[0];
var x = xmlDoc.documentElement;
var newel = xmlDoc.createElement("essy");
x.appendChild(newel);
alert(x.xml);
xmlDoc.save("cart.xml");
}
is it not possible to save xml file on my machine?
Thank you,
In general, browser JavaScript has no I/O API and cannot read or write to the client filesystem since that could be a security loophole. I haven't seen or used the save() method before but it looks like it's an IE specific extension to the XML DOM. If you must use it, this thread might provide the solution, the answer that worked for the OP there suggested:
I haven't proofed your code but here is something you might want to try. I am taking a shot in the dark that you are using this on a Windows OS since you are using IE and from the sound of the error. Just take your html file that you have and rename it the whatever.hta and it will then be able to write to the xml file and save.
Also, the documentation for the method says the following for when the argument is a string (as in your code snippet):
String
Specifies the file name. This must be a file name rather than a URL. The file is created, if necessary, and the contents are replaced entirely with the contents of the saved document. This mode is not intended for use from a secure client, such as Microsoft Internet Explorer.
From the forum posts (links below) that deal with the same issue, I gleaned the following:
This is an IE specific extension and so will only work in IE
There are obviously security restrictions in place so you shouldn't be able to do this 'out of the box'
One workaround that crops up often is to rename the file extension to .hta (Hypertext Application) instead of .html
I'm not sure but there might also be some workarounds by changing the permissions for the security zones your application runs in
References:
http://www.codingforums.com/showthread.php?t=25048
http://p2p.wrox.com/xml/4053-error-using-xml-save-method.html
http://www.daniweb.com/web-development/javascript-dhtml-ajax/threads/204995

Chrome extension: How to save a file on disk

I'm currently creating an extension for google chrome which can save all images or links to images on the harddrive.
The problem is I don't know how to save file on disk with JS or with Google Chrome Extension API.
Have you got an idea ?
You can use HTML5 FileSystem features to write to disk using the Download API. That is the only way to download files to disk and it is limited.
You could take a look at NPAPI plugin. Another way to do what you need is simply send a request to an external website via XHR POST and then another GET request to retrieve the file back which will appear as a save file dialog.
For example, for my browser extension My Hangouts I created a utility to download a photo from HTML5 Canvas directly to disk. You can take a look at the code here capture_gallery_downloader.js the code that does that is:
var url = window.webkitURL || window.URL || window.mozURL || window.msURL;
var a = document.createElement('a');
a.download = 'MyHangouts-MomentCapture.jpg';
a.href = url.createObjectURL(dataURIToBlob(data.active, 'jpg'));
a.textContent = 'Click here to download!';
a.dataset.downloadurl = ['jpg', a.download, a.href].join(':');
If you would like the implementation of converting a URI to a Blob in HTML5 here is how I did it:
/**
* Converts the Data Image URI to a Blob.
*
* #param {string} dataURI base64 data image URI.
* #param {string} mimetype the image mimetype.
*/
var dataURIToBlob = function(dataURI, mimetype) {
var BASE64_MARKER = ';base64,';
var base64Index = dataURI.indexOf(BASE64_MARKER) + BASE64_MARKER.length;
var base64 = dataURI.substring(base64Index);
var raw = window.atob(base64);
var rawLength = raw.length;
var uInt8Array = new Uint8Array(rawLength);
for (var i = 0; i < rawLength; ++i) {
uInt8Array[i] = raw.charCodeAt(i);
}
var bb = new this.BlobBuilder();
bb.append(uInt8Array.buffer);
return bb.getBlob(mimetype);
};
Then after the user clicks on the download button, it will use the "download" HTML5 File API to download the blob URI into a file.
I had long been wishing to make a chrome extension for myself to batch download images. Yet every time I got frustrated because the only seemingly applicable option is NPAPI, which both chrome and firefox seem to have not desire in supporting any longer.
I suggest those who still wanted to implement 'save-file-on-disk' functionality to have a look at this Stackoverflow post, the comment below this post help me a lot.
Now since chrome 31+, the chrome.downloads API became stable. We can use it to programmatically download file. If the user didn't set the ask me before every download advance option in chrome setting, we can save file without prompting user to confirm!
Here is what I use (at extension's background page):
// remember to add "permissions": ["downloads"] to manifest.json
// this snippet is inside a onMessage() listener function
var imgurl = "https://www.google.com.hk/images/srpr/logo11w.png";
chrome.downloads.download({url:imgurl},function(downloadId){
console.log("download begin, the downId is:" + downloadId);
});
Though it's a pity that chrome still doesn't provide an Event when the download completes.chrome.downloads.download's callback function is called when the download begin successfully (not on completed)
The Official documentation about chrome.downloadsis here.
It's not my original idea about the solution, but I posted here hoping that it may be of some use to someone.
There's no way that I know of to silently save files to the user's drive, which is what it seems like you're hoping to do. I think you can ASK for files to be saved one at a time (prompting the user each time) using something like:
function saveAsMe (filename)
{
document.execCommand('SaveAs',null,filename)
}
If you wanted to only prompt the user once, you could grab all the images silently, zip them up in a bundle, then have the user download that. This might mean doing XmlHttpRequest on all the files, zipping them in Javascript, UPLOADING them to a staging area, and then asking the user if they would like to download the zip file. Sounds absurd, I know.
There are local storage options in the browser, but they are only for the developer's use, within the sandbox, as far as I know. (e.g. Gmail offline caching.) See recent announcements from Google like this one.
Google Webstore
Github
I made an extension that does something like this, if anyone here is still interested.
It uses an XMLHTTPRequest to grab the object, which in this case is presumed to be an image, then makes an ObjectURL to it, a link to that ObjectUrl, and clicks on the imaginary link.
Consider using the HTML5 FileSystem features that make writing to files possible using Javascript.
Looks like reading and writing files from browsers has become possible. Some newer Chromium based browsers can use the "Native File System API". This 2020 blog post shows code examples of reading from and writing to the local file system with JavaScript.
https://blog.merzlabs.com/posts/native-file-system/
This link shows which browsers support the Native File System API.
https://caniuse.com/native-filesystem-api
Since Javascript hitch-hikes to your computer with webpages from just about anywhere, it would be dangerous to give it the ability to write to your disk.
It's not allowed. Are you thinking that the Chrome extension will require user interaction? Otherwise it might fall into the same category.

Categories