Related
I want to send an "ajax download request" when I click on a button, so I tried in this way:
javascript:
var xhr = new XMLHttpRequest();
xhr.open("GET", "download.php");
xhr.send();
download.php:
<?
header("Cache-Control: public");
header("Content-Description: File Transfer");
header("Content-Disposition: attachment; filename= file.txt");
header("Content-Transfer-Encoding: binary");
readfile("file.txt");
?>
but doesn't work as expected, how can I do ? Thank you in advance
Update April 27, 2015
Up and coming to the HTML5 scene is the download attribute. It's supported in Firefox and Chrome, and soon to come to IE11. Depending on your needs, you could use it instead of an AJAX request (or using window.location) so long as the file you want to download is on the same origin as your site.
You could always make the AJAX request/window.location a fallback by using some JavaScript to test if download is supported and if not, switching it to call window.location.
Original answer
You can't have an AJAX request open the download prompt since you physically have to navigate to the file to prompt for download. Instead, you could use a success function to navigate to download.php. This will open the download prompt but won't change the current page.
$.ajax({
url: 'download.php',
type: 'POST',
success: function() {
window.location = 'download.php';
}
});
Even though this answers the question, it's better to just use window.location and avoid the AJAX request entirely.
To make the browser downloads a file you need to make the request like that:
function downloadFile(urlToSend) {
var req = new XMLHttpRequest();
req.open("GET", urlToSend, true);
req.responseType = "blob";
req.onload = function (event) {
var blob = req.response;
var fileName = req.getResponseHeader("fileName") //if you have the fileName header available
var link=document.createElement('a');
link.href=window.URL.createObjectURL(blob);
link.download=fileName;
link.click();
};
req.send();
}
You actually don't need ajax at all for this. If you just set "download.php" as the href on the button, or, if it's not a link use:
window.location = 'download.php';
The browser should recognise the binary download and not load the actual page but just serve the file as a download.
Cross browser solution, tested on Chrome, Firefox, Edge, IE11.
In the DOM, add an hidden link tag:
<a id="target" style="display: none"></a>
Then:
var req = new XMLHttpRequest();
req.open("GET", downloadUrl, true);
req.responseType = "blob";
req.setRequestHeader('my-custom-header', 'custom-value'); // adding some headers (if needed)
req.onload = function (event) {
var blob = req.response;
var fileName = null;
var contentType = req.getResponseHeader("content-type");
// IE/EDGE seems not returning some response header
if (req.getResponseHeader("content-disposition")) {
var contentDisposition = req.getResponseHeader("content-disposition");
fileName = contentDisposition.substring(contentDisposition.indexOf("=")+1);
} else {
fileName = "unnamed." + contentType.substring(contentType.indexOf("/")+1);
}
if (window.navigator.msSaveOrOpenBlob) {
// Internet Explorer
window.navigator.msSaveOrOpenBlob(new Blob([blob], {type: contentType}), fileName);
} else {
var el = document.getElementById("target");
el.href = window.URL.createObjectURL(blob);
el.download = fileName;
el.click();
}
};
req.send();
It is possible. You can have the download started from inside an ajax function, for example, just after the .csv file is created.
I have an ajax function that exports a database of contacts to a .csv file, and just after it finishes, it automatically starts the .csv file download. So, after I get the responseText and everything is Ok, I redirect browser like this:
window.location="download.php?filename=export.csv";
My download.php file looks like this:
<?php
$file = $_GET['filename'];
header("Cache-Control: public");
header("Content-Description: File Transfer");
header("Content-Disposition: attachment; filename=".$file."");
header("Content-Transfer-Encoding: binary");
header("Content-Type: binary/octet-stream");
readfile($file);
?>
There is no page refresh whatsoever and the file automatically starts downloading.
NOTE - Tested in the following browsers:
Chrome v37.0.2062.120
Firefox v32.0.1
Opera v12.17
Internet Explorer v11
I prefer location.assign(url);
Complete syntax example:
document.location.assign('https://www.urltodocument.com/document.pdf');
developer.mozilla.org/en-US/docs/Web/API/Location.assign
For those looking a more modern approach, you can use the fetch API. The following example shows how to download a spreadsheet file. It is easily done with the following code.
fetch(url, {
body: JSON.stringify(data),
method: 'POST',
headers: {
'Content-Type': 'application/json; charset=utf-8'
},
})
.then(response => response.blob())
.then(response => {
const blob = new Blob([response], {type: 'application/application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'});
const downloadUrl = URL.createObjectURL(blob);
const a = document.createElement("a");
a.href = downloadUrl;
a.download = "file.xlsx";
document.body.appendChild(a);
a.click();
})
I believe this approach to be much easier to understand than other XMLHttpRequest solutions. Also, it has a similar syntax to the jQuery approach, without the need to add any additional libraries.
Of course, I would advise checking to which browser you are developing, since this new approach won't work on IE. You can find the full browser compatibility list on the following link.
Important: In this example I am sending a JSON request to a server listening on the given url. This url must be set, on my example I am assuming you know this part. Also, consider the headers needed for your request to work. Since I am sending a JSON, I must add the Content-Type header and set it to application/json; charset=utf-8, as to let the server know the type of request it will receive.
#Joao Marcos solution works for me but I had to modify the code to make it work on IE, below if what the code looks like
downloadFile(url,filename) {
var that = this;
const extension = url.split('/').pop().split('?')[0].split('.').pop();
var req = new XMLHttpRequest();
req.open("GET", url, true);
req.responseType = "blob";
req.onload = function (event) {
const fileName = `${filename}.${extension}`;
const blob = req.response;
if (window.navigator.msSaveBlob) { // IE
window.navigator.msSaveOrOpenBlob(blob, fileName);
}
const link = document.createElement('a');
link.href = window.URL.createObjectURL(blob);
link.download = fileName;
link.click();
URL.revokeObjectURL(link.href);
};
req.send();
},
Decoding a filename from the header is a little bit more complex...
var filename = "default.pdf";
var disposition = req.getResponseHeader('Content-Disposition');
if (disposition && disposition.indexOf('attachment') !== -1)
{
var filenameRegex = /filename[^;=\n]*=((['"]).*?\2|[^;\n]*)/;
var matches = filenameRegex.exec(disposition);
if (matches != null && matches[1])
filename = matches[1].replace(/['"]/g, '');
}
This solution is not very different from those above, but for me it works very well and i think it's clean.
I suggest to base64 encode the file server side (base64_encode(), if you are using PHP) and send the base64 encoded data to the client
On the client you do this:
let blob = this.dataURItoBlob(THE_MIME_TYPE + "," + response.file);
let uri = URL.createObjectURL(blob);
let link = document.createElement("a");
link.download = THE_FILE_NAME,
link.href = uri;
document.body.appendChild(link);
link.click();
document.body.removeChild(link);
This code puts the encoded data in a link and simulates a click on the link, then it removes it.
Your needs are covered by
window.location('download.php');
But I think that you need to pass the file to be downloaded, not always download the same file, and that's why you are using a request, one option is to create a php file as simple as showfile.php and do a request like
var myfile = filetodownload.txt
var url = "shofile.php?file=" + myfile ;
ajaxRequest.open("GET", url, true);
showfile.php
<?php
$file = $_GET["file"]
echo $file;
where file is the file name passed via Get or Post in the request and then catch the response in a function simply
if(ajaxRequest.readyState == 4){
var file = ajaxRequest.responseText;
window.location = 'downfile.php?file=' + file;
}
}
there is another solution to download a web page in ajax. But I am referring to a page that must first be processed and then downloaded.
First you need to separate the page processing from the results download.
1) Only the page calculations are made in the ajax call.
$.post("CalculusPage.php", { calculusFunction: true, ID: 29, data1: "a", data2: "b" },
function(data, status)
{
if (status == "success")
{
/* 2) In the answer the page that uses the previous calculations is downloaded. For example, this can be a page that prints the results of a table calculated in the ajax call. */
window.location.href = DownloadPage.php+"?ID="+29;
}
}
);
// For example: in the CalculusPage.php
if ( !empty($_POST["calculusFunction"]) )
{
$ID = $_POST["ID"];
$query = "INSERT INTO ExamplePage (data1, data2) VALUES ('".$_POST["data1"]."', '".$_POST["data2"]."') WHERE id = ".$ID;
...
}
// For example: in the DownloadPage.php
$ID = $_GET["ID"];
$sede = "SELECT * FROM ExamplePage WHERE id = ".$ID;
...
$filename="Export_Data.xls";
header("Content-Type: application/vnd.ms-excel");
header("Content-Disposition: inline; filename=$filename");
...
I hope this solution can be useful for many, as it was for me.
this works for me
var dataObj = {
somekey:"someValue"
}
$.ajax({
method: "POST",
url: "/someController/someMethod",
data: dataObj,
success: function (response) {
const blob = new Blob([response], { type: 'text/csv' });
const downloadUrl = URL.createObjectURL(blob);
const a = document.createElement("a");
a.href = downloadUrl;
a.download = "file.csv";
document.body.appendChild(a);
a.click();
}
});
I am developing a web application using HTML + plain Javascript in the frontend, and Flask as backend. The application sends some ID to the server, the server should generate a report as PDF file and send it back to the client.
I am using Flask for the backend and I have created the following endpoint:
#app.route("/download_pdf", methods=['POST'])
def download_pdf():
if request.method == 'POST':
report_id = request.form['reportid']
print(report_id) //Testing purposes.
// do some stuff with report_id and generate a pdf file.
return send_file('/home/user/report.pdf', mimetype='application/pdf', as_attachment=True)
// I already tried different values for mimetype and as_attachment=False
From the command line I can test the endpoint and I get the right file, and the server console prints the 123 report_id as expected:
curl --form reportid=123 http://localhost:5000/download_pdf >> output.pdf
For the frontend side I created a button that calls a Javascript function:
<button id=pdf_button onclick="generatePdf()"> PDF </button>
The Javascript function looks like this:
function generatePdf(){
var report_list = document.getElementById("report_list")
if (report_list.selectedIndex < 0){
alert("Please, select a report.");
}else{
var req = new XMLHttpRequest();
req.open("POST", "/download_pdf", true);
req.responseType = "document";
req.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
req.onreadystatechange = function(){
console.log(req.readyState)
console.log(req.status)
console.log(req.response)
var link = document.createElement('a')
link.href = req.response;
link.download="report.pdf"
link.click()
}
var selected_value = report_list.options[report_list.selectedIndex].value;
var params="reportid="+selected_value;
req.send(params);
}
};
req.response is null in this case. However, the call to the endpoint has been done correctly, as the backend console prints the report_id as expected.
Already tried:
Using "blob" and "arraybuffer" as responseType as in https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest/Sending_and_Receiving_Binary_Data#Receiving_binary_data_using_JavaScript_typed_arrays
Checking for the HTTP return code, which is always 0.
Calling req.onload instead of req.onreadystatechange. The console shows nothing.
Lastly, the Firefox console shows these 6 messages after pressing the related button (please, observe the console.log() calls in the previous code):
2
0
null
4
0
null
It seems that the Javascript function has been called twice when the button is pressed.
My goal is to get the PDF downloaded. I don't know if what am I doing wrong; I'd thank any help on this.
Finally, I found what the problem was and I post this for the record.
I thought it was unrelated, but the <button> calling the Javascript function was inside a <form>. I checked that the form was updated before the call to the endpoint finished, causing the call to finish prepaturely.
If somebody else needs this as example, a snipet of the final code is as follows:
HTML (both the select and button are not part of a <form>):
<select id="report_list" size=20> ... </select>
...
<button id="pdf_button" onclick="generatePdf()"> PDF </button>
Javascript:
function generatePdf(){
var report_list = document.getElementById("report_list");
var req = XMLHttpRequest();
var selected_value = report_list.options[report_list.selectedIndex].value;
req.open("POST", "/reports/"+selected_value+"/pdf", true);
req.responseType = "blob";
req.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
req.onreadystatechange = function(){
if (this.readyState == 4 && this.status == 200){
var blob = new Blob([this.response], {type: "application/pdf"});
var url = window.URL.createObjectURL(blob);
var link = document.createElement('a');
document.body.appendChild(link);
link.style = "display: none";
link.href = url;
link.download = "report.pdf";
link.click();
setTimeout(() => {
window.URL.revokeObjectURL(url);
link.remove(); } , 100);
}
};
req.send();
}
Flask:
#app.route("/reports/<id>/pdf", methods=['POST'])
def get_pdf(id):
if request.method == 'POST':
return send_file(get_pdf_path(id), mimetype='application/pdf')
I am not sure if this is the best or more elegant way to get this done, but so far it works for me.
Your ajax settings are wrong, they should be like these
req.open("POST", "/download_pdf", true);
req.responseType = "blob";
req.onreadystatechange = function() {
console.log(req.readyState)
console.log(req.status)
const blob = new Blob([req.response]);
const url = window.URL.createObjectURL(blob);
const link = document.createElement('a')
link.href = url
link.download = "report.pdf"
link.click()
}
The response type should be blob and when you get the response, parse it as a blob. After some time, remove the link
setTimeout(() => {
window.URL.revokeObjectURL(url);
link.remove();
}, 100);
I want to send an "ajax download request" when I click on a button, so I tried in this way:
javascript:
var xhr = new XMLHttpRequest();
xhr.open("GET", "download.php");
xhr.send();
download.php:
<?
header("Cache-Control: public");
header("Content-Description: File Transfer");
header("Content-Disposition: attachment; filename= file.txt");
header("Content-Transfer-Encoding: binary");
readfile("file.txt");
?>
but doesn't work as expected, how can I do ? Thank you in advance
Update April 27, 2015
Up and coming to the HTML5 scene is the download attribute. It's supported in Firefox and Chrome, and soon to come to IE11. Depending on your needs, you could use it instead of an AJAX request (or using window.location) so long as the file you want to download is on the same origin as your site.
You could always make the AJAX request/window.location a fallback by using some JavaScript to test if download is supported and if not, switching it to call window.location.
Original answer
You can't have an AJAX request open the download prompt since you physically have to navigate to the file to prompt for download. Instead, you could use a success function to navigate to download.php. This will open the download prompt but won't change the current page.
$.ajax({
url: 'download.php',
type: 'POST',
success: function() {
window.location = 'download.php';
}
});
Even though this answers the question, it's better to just use window.location and avoid the AJAX request entirely.
To make the browser downloads a file you need to make the request like that:
function downloadFile(urlToSend) {
var req = new XMLHttpRequest();
req.open("GET", urlToSend, true);
req.responseType = "blob";
req.onload = function (event) {
var blob = req.response;
var fileName = req.getResponseHeader("fileName") //if you have the fileName header available
var link=document.createElement('a');
link.href=window.URL.createObjectURL(blob);
link.download=fileName;
link.click();
};
req.send();
}
You actually don't need ajax at all for this. If you just set "download.php" as the href on the button, or, if it's not a link use:
window.location = 'download.php';
The browser should recognise the binary download and not load the actual page but just serve the file as a download.
Cross browser solution, tested on Chrome, Firefox, Edge, IE11.
In the DOM, add an hidden link tag:
<a id="target" style="display: none"></a>
Then:
var req = new XMLHttpRequest();
req.open("GET", downloadUrl, true);
req.responseType = "blob";
req.setRequestHeader('my-custom-header', 'custom-value'); // adding some headers (if needed)
req.onload = function (event) {
var blob = req.response;
var fileName = null;
var contentType = req.getResponseHeader("content-type");
// IE/EDGE seems not returning some response header
if (req.getResponseHeader("content-disposition")) {
var contentDisposition = req.getResponseHeader("content-disposition");
fileName = contentDisposition.substring(contentDisposition.indexOf("=")+1);
} else {
fileName = "unnamed." + contentType.substring(contentType.indexOf("/")+1);
}
if (window.navigator.msSaveOrOpenBlob) {
// Internet Explorer
window.navigator.msSaveOrOpenBlob(new Blob([blob], {type: contentType}), fileName);
} else {
var el = document.getElementById("target");
el.href = window.URL.createObjectURL(blob);
el.download = fileName;
el.click();
}
};
req.send();
It is possible. You can have the download started from inside an ajax function, for example, just after the .csv file is created.
I have an ajax function that exports a database of contacts to a .csv file, and just after it finishes, it automatically starts the .csv file download. So, after I get the responseText and everything is Ok, I redirect browser like this:
window.location="download.php?filename=export.csv";
My download.php file looks like this:
<?php
$file = $_GET['filename'];
header("Cache-Control: public");
header("Content-Description: File Transfer");
header("Content-Disposition: attachment; filename=".$file."");
header("Content-Transfer-Encoding: binary");
header("Content-Type: binary/octet-stream");
readfile($file);
?>
There is no page refresh whatsoever and the file automatically starts downloading.
NOTE - Tested in the following browsers:
Chrome v37.0.2062.120
Firefox v32.0.1
Opera v12.17
Internet Explorer v11
I prefer location.assign(url);
Complete syntax example:
document.location.assign('https://www.urltodocument.com/document.pdf');
developer.mozilla.org/en-US/docs/Web/API/Location.assign
For those looking a more modern approach, you can use the fetch API. The following example shows how to download a spreadsheet file. It is easily done with the following code.
fetch(url, {
body: JSON.stringify(data),
method: 'POST',
headers: {
'Content-Type': 'application/json; charset=utf-8'
},
})
.then(response => response.blob())
.then(response => {
const blob = new Blob([response], {type: 'application/application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'});
const downloadUrl = URL.createObjectURL(blob);
const a = document.createElement("a");
a.href = downloadUrl;
a.download = "file.xlsx";
document.body.appendChild(a);
a.click();
})
I believe this approach to be much easier to understand than other XMLHttpRequest solutions. Also, it has a similar syntax to the jQuery approach, without the need to add any additional libraries.
Of course, I would advise checking to which browser you are developing, since this new approach won't work on IE. You can find the full browser compatibility list on the following link.
Important: In this example I am sending a JSON request to a server listening on the given url. This url must be set, on my example I am assuming you know this part. Also, consider the headers needed for your request to work. Since I am sending a JSON, I must add the Content-Type header and set it to application/json; charset=utf-8, as to let the server know the type of request it will receive.
#Joao Marcos solution works for me but I had to modify the code to make it work on IE, below if what the code looks like
downloadFile(url,filename) {
var that = this;
const extension = url.split('/').pop().split('?')[0].split('.').pop();
var req = new XMLHttpRequest();
req.open("GET", url, true);
req.responseType = "blob";
req.onload = function (event) {
const fileName = `${filename}.${extension}`;
const blob = req.response;
if (window.navigator.msSaveBlob) { // IE
window.navigator.msSaveOrOpenBlob(blob, fileName);
}
const link = document.createElement('a');
link.href = window.URL.createObjectURL(blob);
link.download = fileName;
link.click();
URL.revokeObjectURL(link.href);
};
req.send();
},
Decoding a filename from the header is a little bit more complex...
var filename = "default.pdf";
var disposition = req.getResponseHeader('Content-Disposition');
if (disposition && disposition.indexOf('attachment') !== -1)
{
var filenameRegex = /filename[^;=\n]*=((['"]).*?\2|[^;\n]*)/;
var matches = filenameRegex.exec(disposition);
if (matches != null && matches[1])
filename = matches[1].replace(/['"]/g, '');
}
This solution is not very different from those above, but for me it works very well and i think it's clean.
I suggest to base64 encode the file server side (base64_encode(), if you are using PHP) and send the base64 encoded data to the client
On the client you do this:
let blob = this.dataURItoBlob(THE_MIME_TYPE + "," + response.file);
let uri = URL.createObjectURL(blob);
let link = document.createElement("a");
link.download = THE_FILE_NAME,
link.href = uri;
document.body.appendChild(link);
link.click();
document.body.removeChild(link);
This code puts the encoded data in a link and simulates a click on the link, then it removes it.
Your needs are covered by
window.location('download.php');
But I think that you need to pass the file to be downloaded, not always download the same file, and that's why you are using a request, one option is to create a php file as simple as showfile.php and do a request like
var myfile = filetodownload.txt
var url = "shofile.php?file=" + myfile ;
ajaxRequest.open("GET", url, true);
showfile.php
<?php
$file = $_GET["file"]
echo $file;
where file is the file name passed via Get or Post in the request and then catch the response in a function simply
if(ajaxRequest.readyState == 4){
var file = ajaxRequest.responseText;
window.location = 'downfile.php?file=' + file;
}
}
there is another solution to download a web page in ajax. But I am referring to a page that must first be processed and then downloaded.
First you need to separate the page processing from the results download.
1) Only the page calculations are made in the ajax call.
$.post("CalculusPage.php", { calculusFunction: true, ID: 29, data1: "a", data2: "b" },
function(data, status)
{
if (status == "success")
{
/* 2) In the answer the page that uses the previous calculations is downloaded. For example, this can be a page that prints the results of a table calculated in the ajax call. */
window.location.href = DownloadPage.php+"?ID="+29;
}
}
);
// For example: in the CalculusPage.php
if ( !empty($_POST["calculusFunction"]) )
{
$ID = $_POST["ID"];
$query = "INSERT INTO ExamplePage (data1, data2) VALUES ('".$_POST["data1"]."', '".$_POST["data2"]."') WHERE id = ".$ID;
...
}
// For example: in the DownloadPage.php
$ID = $_GET["ID"];
$sede = "SELECT * FROM ExamplePage WHERE id = ".$ID;
...
$filename="Export_Data.xls";
header("Content-Type: application/vnd.ms-excel");
header("Content-Disposition: inline; filename=$filename");
...
I hope this solution can be useful for many, as it was for me.
this works for me
var dataObj = {
somekey:"someValue"
}
$.ajax({
method: "POST",
url: "/someController/someMethod",
data: dataObj,
success: function (response) {
const blob = new Blob([response], { type: 'text/csv' });
const downloadUrl = URL.createObjectURL(blob);
const a = document.createElement("a");
a.href = downloadUrl;
a.download = "file.csv";
document.body.appendChild(a);
a.click();
}
});
I have two AJAX functions: one for an image file upload, one for a form info upload.
File Upload
function uploadFile(insertNodeID, inputFileID){
var img = document.getElementById(inputFileID).files[0];
var form_data = new FormData();
form_data.append('file[]', img, img.name);
var objXML = new XMLHttpRequest();
objXML.onprogress = updateProgress;
objXML.onload = function() {
if(objXML.readyState==4 && objXML.status==200) {
if(objXML.responseText !== 'no'){
document.getElementById(insertNodeID).src = objXML.responseText;
}
else{
errorInOut('There was a problem uploading the file.');
}
}
};
objXML.open('POST', baseURL+'ajax/admin_fileupload/', true);
objXML.send(form_data);
Form Info Upload
function uploadFormInfo(strURL, strData, type) {
strURL = baseURL+'ajax/'+strURL+'/';
var objXML = new XMLHttpRequest();
objXML.onreadystatechange = function() {
if (objXML.readyState == 4 && objXML.status == 200) {
returnXML(objXML.responseText, type);
}
};
objXML.open("POST", strURL, true);
objXML.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
objXML.send(strData);
They both work perfect independently.
The issue I'm running into is when I call the uploadFormInfo(), then call uploadFile(), the document.getElementById(insertNodeID).src does not render the uploaded image. It still uploads the image to the server and the responseText is the correct path to the image. I did a console.log on the .src of the id AFTER the I plugged in the new image and the .src is correct BUT, it never changes in the elements tab in Chome inspect. It also works fine BEFORE I call uploadFormInfo().
I've tried and number of things (sending a separate request header for the uploadFile) and nothing works.
I'm stumped.
I have an only JavaScript page and .asmx page. I want to download file
using only JavaScript how can I download the file. I want to download a particular resume.
I am getting resume here,
var res = data[i].resume;
You may use different third-party libraries:
jQuery.fileDownload
It takes URL as an input and downloads a file while shows a loading dialog.
Github: https://github.com/johnculviner/jquery.fileDownload
Demo: http://jqueryfiledownload.apphb.com/
Usage:
$.fileDownload(requestUrl, {
preparingMessageHtml: "Downloading...",
failMessageHtml: "Error, please try again."
});
FileSaver.js
It takes Blob object as an input and downloads it. Blob can be acquired using XMLHttpRequest.
Github: https://github.com/eligrey/FileSaver.js/
Demo: http://eligrey.com/demos/FileSaver.js/
Usage:
var xhr = new XMLHttpRequest();
xhr.open("GET", requestUrl);
xhr.responseType = "blob";
xhr.onload = function () {
saveAs(this.response, 'filename.txt'); // saveAs is a part of FileSaver.js
};
xhr.send();
It may also be used to save canvas-based images, dynamically generated text and any other Blobs.
Or write it yourself
function saveData(blob, fileName) // does the same as FileSaver.js
{
var a = document.createElement("a");
document.body.appendChild(a);
a.style = "display: none";
var url = window.URL.createObjectURL(blob);
a.href = url;
a.download = fileName;
a.click();
window.URL.revokeObjectURL(url);
}
Now, if it is a text file, you can simply download it, create a blob, and save it:
$.ajax({
url: requestUrl,
processData: false,
dataType: 'text'
}).done(function(data) {
var blob = new Blob([data], { type: "text/plain; encoding=utf8" });
saveData(blob, 'filename.txt');
});
Or you can use XMLHttpRequest which works great for any types of files, including binary:
var xhr = new XMLHttpRequest();
xhr.open("GET", requestUrl);
xhr.responseType = "blob";
xhr.onload = function () {
saveData(this.response, 'filename'); // saveAs is now your function
};
xhr.send();
Here is the working demo. Note that this fiddle downloads a file right after opening it. The file is just a random source file from GitHub.
Actually, There is a javascript library called FileSaver.js, FileSaver.js saving file on the client-side. it can help you achieve this.
here: https://github.com/eligrey/FileSaver.js
Usage:
<script src="http://cdn.jsdelivr.net/g/filesaver.js"></script>
<script>
function SaveAsFile(t,f,m) {
try {
var b = new Blob([t],{type:m});
saveAs(b, f);
} catch (e) {
window.open("data:"+m+"," + encodeURIComponent(t), '_blank','');
}
}
SaveAsFile("text","filename.txt","text/plain;charset=utf-8");
</script>
If you use jQuery you can do some like that:
var getFile = function( path_to_file, callback ) {
$.ajax( {
url: path_to_file,
success: callback
} );
};
getFile( 'path_to_your_asmx_page', function( file_as_text ) {
console.log( file_as_text );
} );
Call getFile and you'll get file content in callback function
Use the code below.
var sampleBytes = base64ToArrayBuffer('THISISTHETESTDATA');
saveByteArray([sampleBytes], 'ashok.text');
function base64ToArrayBuffer(base64)
{
var binaryString = window.atob(base64);
var binaryLen = binaryString.length;
var bytes = new Uint8Array(binaryLen);
for (var i = 0; i < binaryLen; i++)
{
var ascii = binaryString.charCodeAt(i);
bytes[i] = ascii;
}
return bytes;
}
var saveByteArray = (function ()
{
var a = document.createElement("a");
document.body.appendChild(a);
a.style = "display: none";
return function (data, name) {
var blob = new Blob(data, {type: "text/plain"}),
url = window.URL.createObjectURL(blob);
a.href = url;
a.download = name;
a.click();
window.URL.revokeObjectURL(url);
};
}());