Reputation: 7014
I'm integrating an intranet with a document management system. The DMS has a SOAP API. We've built a client that receives REST calls, makes the SOAP calls, and returns JSON or document data.
The problem is all of the solutions for AJAX filedownload seem to use iFrame (see John Culniver's filedownload plugin).
I can't use this because I need to provide authentication credentials in the header. The only other potential solution I can think of is using window.open
(if I can get past browser popup blocking).
Does anyone have another potential solution or how might do this with window.open??
Thanks
Upvotes: 2
Views: 2763
Reputation: 6548
I was able to do it successfully. I'm my example I'm using Basic Authentication however you can replace your Authorization header with different value (e.g you can replace it with Bearer Yourtokenvalue
.
Here is the code snippet
$(document).on("click", "#btn", function() {
var username = "yourUserNameForBasicAuthentication";
var password = "yourPasswordForBasicAuthentication"
console.log("button clicked");
var request = new XMLHttpRequest();
request.open("GET", $("#txtUrl").val().trim(), true);
//Set the authorization headers
request.setRequestHeader("Authorization", "Basic " + window.btoa(username + ":" + password));
//Set the Response type as blob which means raw data
request.responseType = "blob";
//We will initiate a default file name in case no file name is detected later on from headers of HTTP Request
var fileName = "unnamed.pdf";
request.onload = function(event) {
if (request.status == 200) {
console.log("success response received");
var blob = request.response;
//Getting contenttype from response headers
var contentType = request.getResponseHeader("content-type");
if (contentType == null) {
contentType = "application/pdf";
}
//Check 'Content-Disposition' header to get filename of file (if possible)
if (request.getResponseHeader("Content-Disposition")) {
var contentDisposition = request.getResponseHeader("Content-Disposition");
fileName = contentDisposition.substring(contentType.indexOf("=") + 1);
}
if (window.navigator.msSaveOrOpenBlob) {
// Internet Explorer
window.navigator.msSaveOrOpenBlob(new Blob([blob], {
type: contentType
}), fileName);
} else {
var el = document.createElement("a");
document.body.appendChild(el);
el.href = window.URL.createObjectURL(blob);
el.download = fileName;
el.click();
el.remove();
window.URL.revokeObjectURL(el.href);
}
} //end of Status code
else {
alert("System failed to authenticate");
}
} //End of event
request.send();
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<input type="text" value="https://yoursamplefile.txt" id="txtUrl" style="width:100%" /><br />
<input type='button' value='Download File' id='btn' />
Upvotes: 1
Reputation: 6655
I don't think there is a client-side solution for this problem. window.open
isn't going to let you set the request headers. You'll need to do something like send a cookie or some other value to the server and add server-side code that alleviates the need for the request header.
See the answers to:
Upvotes: 2