Downloading Excel (.xlsx) File In Frontend Javascript Via Amazon Presigned URL - javascript

I have an amazon S3 URL being passed back to me from an external service that is in the format:
https://foo.s3.amazonaws.com/ProjectDownloads/foo/title.xlsx?AWSAccessKeyId=foo&Expires=1602279238&Signature=foo
I haven't worked much with S3, but my understanding is this is a Presigned URL - I can paste it in my browser and the excel file downloads.
How can I download this file directly using javascript (on the frontend, as my system is not running node)?
I have tried generating an tag element with click - however all my files download as corrupt. I can download the file directly by pasting the link in my browser and it auto initiates a download.
Any help will be appreciated.
I have tried the following, but it downloads a file with error:
var link = document.createElement('a');
link.href = url;
link.download = 'foo.xlsx';
document.body.appendChild(link);
link.click();
document.body.removeChild(link);

You don’t need JS to force a download on clicking the link; you can do this with just HTML. And, it doesn’t matter that the source is a presigned S3 URL - it works with any URL.
<a href=“Foo.xlsx” download>click to download</a> should do it for you.
Have a look at https://www.w3schools.com/howto/howto_html_download_link.asp for the browser support matrix.

Related

Change file extension of download link - JavaScript

I have a script that receives a download link from an API request. If you click the link, it automatically downloads the file with no file extension. I need the script to return a CSV file. What is the simplest way of handling this?
In essence, I want the following Python code in JavaScript.
r = requests.get(base64ToString(get_log_files(getlog_ID("APIKEY"))['log_csv_url_b64']), allow_redirects=True)
open('flight.csv', 'wb').write(r.content)
This is the code I have now written in JavaScript, a language I am a complete novice in. Currently it downloads a blank CSV file to the user.
let blob = await response.blob();
let link = document.createElement("a");
link.href = URL.createObjectURL(blob);
link.download = "flight.csv";
link.click();

Javascript function force downloads an MP3 file from URL, once downloaded however MP3 file wont play on my computer only on VLC Player? Why?

I have a Javascript function that basically force downloads a file once provided the URL and name of the file. This function works absolutely fine as intended I call it from a HTML tag/hyperlink. But once the MP3 file from my function downloads it wont play on my computer. I have designed this function for a user to be able to download different MP3 and WAV files upon clicking on the associated link for that file. I can only play the downloaded MP3 file on the media player VLC it won't play on my laptop. Is there something I am doing to the MP3 file in the download process with my function or why will it not play once downloaded?
I have looked into MP3 file variations and encoding but Im not sure what to look for really or what I am doing wrong. When I download MP3 files from other sites they are working fine and play straight away.
Function:
<script>// <![CDATA[
function downloadFile(data, fileName, type="text/plain") {
// Create an invisible A element
const a = document.createElement("a");
a.style.display = "none";
document.body.appendChild(a);
// Set the HREF to a Blob representation of the data to be downloaded
a.href = window.URL.createObjectURL(
new Blob([data], { type })
);
// Use download attribute to set set desired file name
a.setAttribute("download", fileName);
// Trigger the download by simulating click
a.click();
// Cleanup
window.URL.revokeObjectURL(a.href);
document.body.removeChild(a);
}
// ]]></script>
Function Call:
My Download
If you look in the downloaded file, you'll find it contains the text https://cdn.shopify.com/s/files/1/0037/4951/1217/files/ascence-places-like-that-ncs-release.mp3?360 because that's the value you're passing for data and using when creating the blob. Nothing about that code creating a blob downloads the content (and the SOP prevents your code from downloading the content, unless of course the other site overrides it with CORS).
I don't think you can force the link to open the Save dialog. Normally that's triggered by the response to the link from the server (via the Content-Disposition header), which of course you can't control in your scenario. Using the download attribute won't do it, it has no effect cross-origin (other than when the link is a data: or blob: URL, see MDN's description).
You can show them the link so they can right-click and choose "Save target as...", but I know that's going to be a disappointing answer for you.

Instead of downloading, files are opening in browser

My Pdf file is stored in google bucket, and i have a link let say https://storage.googleapis.com/bucketName/xyz.pdf. To download this file i am doing this,
<a href="https://storage.googleapis.com/bucketName/xyz.pdf" download> Download This File </a>
But when i click on this anchor tag, instead of downloading this file browser open this file in same tab even i try to download the file via javascript and was using this code .
var link = document.createElement("a");
link.download = 'File.pdf';
link.href = 'https://storage.googleapis.com/bucketName/xyz.pdf';
link.click();
But same happen again file open in same tab instead of downloading. I don't know what is the main problem ? Is this Google bucket is not letting file to download, or my chrome setting preventing files to download.
It is not downloading in Chrome i guess Chrome do allow the downloading from CORS files.
As per JavaScript/jQuery to download file via POST with JSON data construct a blob and use that to return the file reference for the link.
This will inform the browser of your intent in a standards compliance manner.
example ...
$.get(/*...*/,function (result)
{
var blob=new Blob([result]);
var link=document.createElement('a');
link.href=window.URL.createObjectURL(blob);
link.download="myFileName.txt";
link.click();
});
Solution
Content-Disposition attachment seems to work for me:
self.set_header("Content-Type", "application/json")
self.set_header("Content-Disposition", 'attachment; filename=learned_data.json')
Workaround
application/octet-stream
I had something similar happening to me with a JSON, for me on the server side I was setting the header to
self.set_header("Content-Type", "application/json")
however when i changed it to:
self.set_header("Content-Type", "application/octet-stream")
It automatically downloaded it.
Also know that in order for the file to still keep the .json suffix you will need to it on filename header:
self.set_header("Content-Disposition", 'filename=learned_data.json')
Try link.target = "_blank"; this will open file in new tab and link.download will force it download.
Please tell if this works.

Add downloadable file to another page with JavaScript in Google App Engine

I'm relatively new to Google App Engine and JavaScript, so I'm really not sure if I'm following good practice for this or anything, but here goes.
I have a game running on one page of my web application where I am collecting data on the user's movement and putting it in a csv file (i.e. I am creating a csv file in my JavaScript code). I have created a link that will automatically download the file on that specific page, but what I really want to do is add a link to download the file to a different page of my site. Is there any easy way to do this in JavaScript?
This is my current download code (where csvContent is a global variable with all the info I need in my csv)
//download csv file
function downloadData() {
var encodedUri = encodeURI(csvContent);
var link = document.createElement("a");
link.setAttribute("href", encodedUri);
link.setAttribute("download", "game1_data.csv");
document.body.appendChild(link); // Required for FF
link.click();
}
Ideally there would be a way to output the file to somewhere besides my current doc (like a different path on the website). For example, if I were on a page '/game', I'd want to create an element on '/files'.
If you just want to store file for user locally and give option to download within your domain pages, you can use fileSystem API (supported by chrome and opera) or Indexed db (supported by most browsers) to store locally in browser.
Refer here - How to store file in a browser using JavaScript
If you intend to save the file on server use google cloud storage1. You get 5 gb storage and 1 bucket free with google cloud. This way user can view/download it anywhere.

How to get a web browser to download a file that is stored in a JavaScript String?

I've been able to write JavaScript to cause the browser to download a file from a remote server using code like this:
var iframe = document.createElement("iframe");
iframe.style.display = "none";
iframe.src = "filename.zip"
document.body.appendChild(iframe);
Which works great. However, now I have a different situation where the contents of the file are stored in a string in my JavaScript on the browser side and I need to trigger a download of that file. I've tried replacing the third line above with this, where 'myFileContents' is the string containing the actual bytes of the file:
iframe.src = "data:application/octet-stream;base64," + Base64.encode(myFileContents);
This gets the file downloaded, but the file name is lost. In Chrome the file name is just 'download'. Also I've read that there are limitations to the file size allowed in some browser versions.
Is there a way to achieve this? Using JQuery would be OK. The solution needs to support any file type - zip, pdf, csv, png, jpg, xls, etc...
In some newer browsers you can use the new HTML5 download attribute on the a tag to achieve this:
var a = document.createElement('a');
a.download = "filename.txt";
a.href = "data:application/octet-stream;base64," + Base64.encode(myFileContents);
a.click();
For a future solution you could look into the HTML5 FileSystem API, but this API is not currently supported in most of the major browsers. It might not be of much use to you except for that it might provide you with another way to store the files locally if you would be OK with that. But it doesn't store the files on the users locally accessible file system, you would have to develop your own browser based interface for your users to interact with the files. Downloading the files from the HTML5 file system to the users local file system would in any case again be done using the new download attribute on an a tag, which would then refer to a location in the HTML5 file system instead of referring to an online location.
To do this with an iframe element you would have to somehow set the Content-Disposition request header on the iframe to inline; filename="filename.txt" using client side JavaScript, I don't think it is possible to do this, most likely because of security issues. If you really don't have any other option, you could kill the download speed performance by sending the string to the server using AJAX and then downloading it from there again with the right request headers set.

Categories

Resources