Force downloading a file is not working in Safari browser - javascript

I'm downloading a file from cross-domain and its working both in chrome and Firefox but not working in safari. Both Chrome and Firefox are downloading where as Safari is playing the song. It's safari bug but solved by somebody and I didn't quite get it. Please do help me.
Note: Giving a small error : Failed to load resource: Frame load interrupted
Clientside code:
var url = "http://www.example.com/song.mp3";
var xhr = createCORSRequest('GET', url);
if (!xhr) {
alert('CORS not supported');
return;
}
xhr.responseType = 'blob';
xhr.onload = function() {
var a = document.createElement('a');
a.href = window.URL.createObjectURL(xhr.response);
a.download = 'FileName.mp3';
a.style.display = 'none';
document.body.appendChild(a);
a.click();
delete a;
};
xhr.onerror = function() {
alert('Woops, there was an error making the request.');
};
xhr.send();
}
function createCORSRequest(method, url) {
var xhr = new XMLHttpRequest();
if ("withCredentials" in xhr) {
// XHR for Chrome/Firefox/Opera/Safari.
xhr.open(method, url, true);
} else if (typeof XDomainRequest != "undefined") {
// XDomainRequest for IE.
xhr = new XDomainRequest();
xhr.open(method, url);
} else {
// CORS not supported.
xhr = null;
}
return xhr;
}
ServerSide Code:
.htaccess file
<FilesMatch "\.('mp3')$">
ForceType application/octet-stream
Header set Content-Disposition attachment
</FilesMatch>

The problem is browser compatibility of Safari browser in effective usage of the Blobs. So I just removed the above snippet and used the basic anchor tag for my operations.
if(navigator.userAgent.indexOf("Safari") != -1){
var a = $("<a>").attr("href", url).attr("download", "MyFile.mp3").appendTo("body");
a[0].click();
a.remove();
}

Related

export to excel file not working in firefox

I am using below javascript to export data to excel file.below script is working fine in chrome(file is getting downloaded) but file is not getting downloaded and no errors are also coming in firefox console(I see this message 'Successfully downloaded excel.' in firefox console).
var req = new XMLHttpRequest();
req.open("POST", "xxxxx/exportapi/exportmetadata", true); //calling Rest API
req.setRequestHeader('Content-type', 'application/json; charset=utf-8');
req.responseType = "blob";
req.onload = function(e) {
if (this.status == 200) {
var blob = this.response;
var downloadLink = domConstruct.create("a", {
href: window.URL.createObjectURL(new Blob([blob], { type: 'application/vnd.ms-excel' })),
download: "ExportExcelDataList.xlsx"
});
downloadLink.click();
console.log('Successfully downloaded excel.')
}
else {
console.log('Unable to download excel.')
}
};
req.send(json);
Try adding
document.body.appendChild(downloadLink);
before
downloadLink.click();
For reference, view the given link Excel export not working on Firefox but working fine in google crome

Zip download is not happening

Hi I am new to java script, I am trying to download zip file from a web server running in http://10.1.2.137:5000/download.
When I access the URL alone in the browser as http://10.1.2.137:5000/download, te zip file is getting downloaded , but when I call from java script , the zip file is getting corrupted it seems. Not able to open the zip file with win rar.
Not sure this is the issue with CORS.
$scope.downloadData = function (){
console.log ('Entering in to Download Method')
var url = 'http://10.1.2.137:5000/download';
var xhr = new XMLHttpRequest();
xhr.open("GET", url);
xhr.setRequestHeader("Content-Type", "application/json;charset=UTF-8");
xhr.setRequestHeader("Access-Control-Allow-Origin", "*");
xhr.responseType = "arraybuffer";
var linkElement = document.createElement('iframe');
document.body.appendChild(linkElement)
xhr.send();
xhr.onreadystatechange = function() {
if (xhr.readyState == 4 && xhr.status == 200) {
var blob = new Blob([str2bytes(xhr.response)], {type: "application/zip"});
var fileName = "logs.zip";
if (window.navigator && window.navigator.msSaveOrOpenBlob) {
window.navigator.msSaveOrOpenBlob(blob, filename);
} else {
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);
a.remove();
}
}
}
};
You can use window.open, this will instruct the browser to open the url and start download. e.g.
window.open("http://10.1.2.137:5000/download","_self");

How to download files using Springboot #RestController via ajax

I have an Springboot rest controller to download a file. I am trying to access the endpoint using the browser and able to see the response in the xhr.response. However, i want to force the file download which i am not able to achieve.
The code is as follows :
Rest based endpoint (Springboot):
#GetMapping(value = "download/{id}", produces = MediaType.APPLICATION_OCTET_STREAM_VALUE, consumes = "*/*")
public ResponseEntity<InputStreamResource> getFile(#PathVariable("id") Long contractId) {
Contract contract;
contract = this.contractRepository.findOne(contractId);
System.out.println(contract.getPath()); // test
InputStreamResource resource = null;
HttpHeaders respHeaders = new HttpHeaders();
if (contract != null) {
try {
File file = new File(contract.getPath());
FileInputStream fileInputStream = new FileInputStream(file);
resource = new InputStreamResource(fileInputStream);
System.out.println(resource.exists());//test
respHeaders.add("Content-Type", URLConnection.guessContentTypeFromStream(fileInputStream));
respHeaders.add("Cache-Control", "no-cache, no-store, must-revalidate");
respHeaders.add("Pragma", "no-cache");
respHeaders.add("Expires", "0");
respHeaders.add("Content-Disposition", "attachment;filename=" + file.getName());
respHeaders.add("Content-Transfer-Encoding", "Binary");
respHeaders.setContentLength(file.length());
} catch (IOException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
}
return new ResponseEntity<InputStreamResource>(
this.companyService.downloadContract(contractId),
respHeaders,
HttpStatus.OK
);
}
My xhr request is as follows
var xhr = new XMLHttpRequest();
xhr.open("GET", http.getHRTargetURL() + "download/" + id, true);
xhr.setRequestHeader("X-Auth-Token", http.getToken());
xhr.setRequestHeader("Accept", "application/octet-stream");
xhr.setRequestHeader("Content-Type", "application/octet-stream");
xhr.onreadystatechange = function () {
if (xhr.readyState == 4 && xhr.response != "0") {
console.log(xhr)
console.log("Downloaded file");
} else {
console.log("error downloading document")
}
}
xhr.send();
I am able to get the response from the endpoint . I can see the file contents in the xhr response on the browser
My problem is how can I force this response to popup file save wizard on the browser.
You could try like this.
xhr.onreadystatechange = function () {
if (xhr.readyState == 4 && xhr.response != "0") {
console.log(xhr)
var windowUrl = window.URL || window.webkitURL;
var url = windowUrl.createObjectURL(xhr);
anchor.prop('href', url);
anchor.prop('download', "filename");
anchor.get(0).click();
windowUrl.revokeObjectURL(url);
console.log("Downloaded file");
} else {
console.log("error downloading document")
}
}
xhr.send();
Well as I figured out that problem was with the frontend and had nothing to do with backend as Springboot was sending the proper response back.
Building on the answer provided by Dinesh above i modified my answer as follows
download(id, name){
var xhr = new XMLHttpRequest();
xhr.open("GET", http.getHRTargetURL() + "download/" + id, true);
xhr.setRequestHeader("X-Auth-Token", http.getToken());
xhr.setRequestHeader("Content-Type", "application/octet-stream");
xhr.responseType = "blob";
xhr.onreadystatechange = function () {
if (xhr.readyState == 4) {
var a = document.createElement("a");
document.body.appendChild(a);
a.style = "display: none";
var url = window.URL.createObjectURL(new Blob([xhr.response], {type: "octet/stream"}));
a.href = url;
a.download = name;
a.click();
window.URL.revokeObjectURL(url);
} else {
console.log("error downloading document")
}
}
xhr.send();
}

Reading xml file from internet-Cross Origin Request Error on Firefox

I am trying to read xml file on the internet.It works on IE but does not on Firefox/Chrome.
It gives the error below on Firefox;
Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at http://xxxxx.com/YYYY.xml. This can be fixed by moving the resource to the same domain or enabling CORS.
Here is my code;
<html>
<head>
<script>
function loadXMLDoc(filename)
{
if (window.ActiveXObject)
{
xhttp = new ActiveXObject("Msxml2.XMLHTTP");
}
else
{
xhttp = new XMLHttpRequest();
}
xhttp.open("GET", filename, false);
try {xhttp.responseType = "msxml-document"} catch(err) {} // Helping IE11
xhttp.send("");
return xhttp.responseXML;
}
function displayResult()
{
xml = loadXMLDoc("http://xxxxx.com/YYYY.xml");
...........
.........
}
</script>
</head>
<body onload="displayResult()">
<div id="example" />
</body>
</html>
It returns null on the line
xhttp.responseXML;
in the loadXMLDoc function.
After getting this error I googled the error and tried the code below which makes CORS request. But it also does now work.
// Create the XHR object.
function createCORSRequest(method, url) {
var xhr = new XMLHttpRequest();
if ("withCredentials" in xhr) {
// XHR for Chrome/Firefox/Opera/Safari.
xhr.open(method, url, true);
} else if (typeof XDomainRequest != "undefined") {
// XDomainRequest for IE.
xhr = new XDomainRequest();
xhr.open(method, url);
} else {
// CORS not supported.
xhr = null;
}
return xhr;
}
// Helper method to parse the title tag from the response.
function getTitle(text) {
return text.match('<title>(.*)?</title>')[1];
}
// Make the actual CORS request.
function makeCorsRequest() {
// All HTML5 Rocks properties support CORS.
var url = 'http://xxxxx.com/YYYY.xml';
var xhr = createCORSRequest('GET', url);
if (!xhr) {
alert('CORS not supported');
return;
}
// Response handlers.
xhr.onload = function() {
var text = xhr.responseText;
var title = getTitle(text);
alert('Response from CORS request to ' + url + ': ' + title);
};
xhr.onerror = function() {
alert('Woops, there was an error making the request.');
};
xhr.send();
}
In makeCorsRequest() function, after createCORSRequest() function, xhr.responseText is "" and xhr.ResponseXML is null.In response handler, it gives xhr.onerror.
Could you help me about this error?
Thanks.
UPDATE:
I am trying to test my pages in my computer(localhost). On the IIS in my computer, I enabled the CORS with the web.config below
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<system.webServer>
<httpProtocol>
<customHeaders>
<add name="Access-Control-Allow-Origin" value="*" />
</customHeaders>
</httpProtocol>
</system.webServer>
</configuration>
On the network tab of the developer tab of Firefox
http://imgur.com/CXzxHLj
You have to enable CORS on the server hosting http://xxxxx.com/YYYY.xml, not on the server hosting your HTML document (which is localhost in your example).
You can't give yourself permission to access another server.

Downloading mp3 files using html5 blobs in a chrome-extension

I am trying to create a google-chrome-extension that will download an mp3 file. I am trying to use HTML5 blobs and an iframe to trigger a download, but it doesn't seem to be working. Here is my code:
var finalURL = "server1.example.com/u25561664/audio/120774.mp3";
var xhr = new XMLHttpRequest();
xhr.open("GET", finalURL, true);
xhr.setRequestHeader('Content-Type', 'application/octet-stream');
xhr.onreadystatechange = function()
{
if(xhr.readyState == 4 && xhr.status == 200)
{
var bb = new (window.BlobBuilder || window.WebKitBlobBuilder)();
bb.append(xhr.responseText);
var blob = bb.getBlob("application/octet-stream");
var saveas = document.createElement("iframe");
saveas.style.display = "none";
saveas.src = window.webkitURL.createObjectURL(blob);
document.body.appendChild(saveas);
delete xhr;
delete blob;
delete bb;
}
}
xhr.send();
When looked in the console, the blob is created correctly, the settings look right:
size: 15312172
type: "application/octet-stream"
However, when I try the link created by the createObjectURL(),
blob:chrome-extension://dkhkkcnjlmfnnmaobedahgcljonancbe/b6c2e829-c811-4239-bd06-8506a67cab04
I get a blank document and a warning saying
Resource interpreted as Document but
transferred with MIME type
application/octet-stream.
How can get my code to download the file correctly?
The below code worked for me in Google chrome 14.0.835.163:
var finalURL = "http://localhost/Music/123a4.mp3";
var xhr = new XMLHttpRequest();
xhr.overrideMimeType("application/octet-stream");
//xhr.setRequestHeader('Access-Control-Allow-Origin', '*');
xhr.open("GET", finalURL, true);
xhr.responseType = "arraybuffer";
xhr.onload = function() {
var bb = new (window.BlobBuilder || window.WebKitBlobBuilder)();
var res = xhr.response;
if (res){
var byteArray = new Uint8Array(res);
}
bb.append(byteArray.buffer);
var blob = bb.getBlob("application/octet-stream");
var iframe = document.createElement("iframe");
iframe.style.display = "none";
iframe.src = window.webkitURL.createObjectURL(blob);
document.body.appendChild(iframe);
};
xhr.send(null);
I'm not sure, but i think this is your server's trouble. I've just tried your piece of code to download some sample blob of mp3-file and everything went ok. So maybe:
this file doesn't exist on your server
you server outputs wrong mime type for mp3 files

Categories