I have an ajax call where I am calling JSReport and downloading the pdf document. In chrome and other browsers, it works correctly. The document is downloaded and I can open it. But in IE11, the document is downloaded but if I want to open the pdf file, it always shows failed to load pdf document. I debugged the code in IE11 console, but it did not give any error.
Here is my code,
$.ajax({
url: 'my api url',
headers: { 'Accept': 'application/json', 'Content-Type': 'application/json' },
type: 'POST',
data: JSON.stringify(selectedIds),
success: function (data) {
var a = document.createElement('a');
var isIE = false || !!document.documentMode;
if (!isIE) {
// This part is working properly
for (var i = 0; i < data.length; i++) {
a.href = "data:application/octet-stream;base64," + data[i];
a.target = '_blank';
a.download = 'report.pdf';
a.click();
}
} else {
// This part is for IE11 browser where I have problem to load the document after download
for (var i = 0; i < data.length; i++) {
var file = new Blob([data[i]], {
type: 'application/octet-stream'
});
window.navigator.msSaveOrOpenBlob(file, 'report.pdf');
}
}
},
fail: function (jqXHR, textStatus) {
alert("Request failed: " + textStatus);
}
});
Finally, I found the solution! I actually needed to convert base64 string data to Blob. Then we can download it. Previously, it was not converted correctly. This was why the file was downloaded but failed to load since it was damaged. Here is my code is given below,
$.ajax({
url: 'my api url',
headers: { 'Accept': 'application/json', 'Content-Type': 'application/json' },
type: 'POST',
data: JSON.stringify(selectedIds),
success: function (data) {
var a = document.createElement('a');
var isIE = false || !!document.documentMode;
if (!isIE) {
// This part is working properly
for (var i = 0; i < data.length; i++) {
a.href = "data:application/octet-stream;base64," + data[i];
a.target = '_blank';
a.download = 'report.pdf';
a.click();
}
} else {
for (var i = 0; i < data.length; i++) {
var base64Data = data[i];
var fileName = 'report.pdf';
var byteCharacters = atob(base64Data);
var byteNumbers = new Array(byteCharacters.length);
for (var j = 0; j < byteCharacters.length; j++) {
byteNumbers[j] = byteCharacters.charCodeAt(j);
}
var byteArray = new Uint8Array(byteNumbers);
var blob = new Blob([byteArray], { type: 'application/pdf' });
window.navigator.msSaveOrOpenBlob(blob, fileName);
}
}
},
fail: function (jqXHR, textStatus) {
alert("Request failed: " + textStatus);
}
});
Related
This code works great on tablets and desktop, but when I try on iPhone it is not downloading any file. Please help
if (aData.ExternalUrl === "") {
this.oModel.read("/GetAttachmentBase64Set('" + aData.DocumentId + "')", {
success: function (oData, oResponse) {
oList.setBusy(false);
var dataURI = oData.EvAttachmentData;
if (Device.system.tablet ||Device.system.phone) {
window.open(dataURI, "_blank");
return;
}
dataURI = dataURI.substring(dataURI.indexOf(",") + 1);
var raw = window.atob(dataURI);
var rawLength = raw.length;
var array = new Uint8Array(new ArrayBuffer(rawLength));
for (var i = 0; i < rawLength; i++) {
array[i] = raw.charCodeAt(i);
}
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: "octet/stream"
}),
url = window.URL.createObjectURL(blob);
a.href = url;
a.download = name;
a.click();
window.URL.revokeObjectURL(url);
};
}());
saveByteArray([array], aData.Filename);
oList.removeSelections();
},
This code works great on tablets and desktop, but when I try on iPhone it is not downloading any file. Please help
I am getting this error that Chrome failed to load the PDF document. I can see the content of the data is the console window so I have the data being returned I just not sure why it will not display? If I File.WriteAllBytes to disk it will open fine so it maybe something with the creating the new Blob
Failed to load PDF document.
ts code
printItems(versionKeys: string[]): JQueryPromise<any> {
console.log('printItems');
$.ajax({
type: "post",
contentType: "application/json",
data: JSON.stringify(versionKeys),
url: this.apiUrls.PrintTemplates,
success: function (data, status, xhr) {
console.log('printItems');
console.log(data);
let blob = new Blob([data.Content], { type: data.ContentType });
var url = URL.createObjectURL(blob);
console.log(url);
window.open(url);
console.log('success');
}
});
return;
}
Error
I converted the base64 string to a bytes
var binary_string = window.atob(data.Content)
var len = data.Content.length;
var bytes = new Uint8Array(len);
for (var i = 0; i < len; i++) {
bytes[i] = binary_string.charCodeAt(i);
}
let blob = new Blob([bytes.buffer], { type: data.ContentType })
var url = URL.createObjectURL(blob);
window.open(url);
I'm trying to record a video (already working) using HTML5 video tag, "getUserMedia" to access the device camera and MediaRecorder API to capture the frames and Angular1 to handle the file uploading. Now I'm having trouble uploading the Blob to my PHP server which is running on Laravel, I currently have 2 ways to upload the video, first is by "ng-click" this works fine but when I programmatically upload the Blob using the same function which "ng-click" run it seems to break the mimeType of my Blob here's how my code looks.
$scope.uploader = function() {
let fData = new FormData();
let blob = new Blob($scope.chunk, { type: 'video/webm' });
fData.append('vid', blob)
$http.post(url, fData, {
transformRequest: angular.identity,
headers: {'Content-Type': undefined},
}, success, error)
})
$timeout(function() {
$scope.uploader();
}, 10000)
This issue here is when the "$scope.uploader()" is called using "ng-click" it works fine but when calling the "uploader" method using the "$timeout" it seems to change the mimeType to "application/octet-stream" which causes the issue.
Hello Try this code,
function base64ToBlob(base64Data, contentType) {
contentType = contentType || '';
var sliceSize = 1024;
var byteCharacters = atob(base64Data);
var bytesLength = byteCharacters.length;
var slicesCount = Math.ceil(bytesLength / sliceSize);
var byteArrays = new Array(slicesCount);
for (var sliceIndex = 0;sliceIndex <slicesCount;++sliceIndex) {
var begin = sliceIndex * sliceSize;
var end = Math.min(begin + sliceSize, bytesLength);
var bytes = new Array(end - begin);
for (var offset = begin, i = 0;offset <end;++i, ++offset) {
bytes[i] = byteCharacters[offset].charCodeAt(0);
}
byteArrays[sliceIndex] = new Uint8Array(bytes);
}
return new Blob(byteArrays, {
type: contentType});
}
Define scope
$scope.onFile = function(blob) {
Cropper.encode((file = blob)).then(function(dataUrl) {
$scope.dataUrl = dataUrl;
$scope.odataUrl = dataUrl;
$timeout(showCropper); // wait for $digest to set image's src
});
};
Submit method
$scope.uploadImage = function () {
if ($scope.myCroppedImage === '')
{
}
$scope.msgtype = "";
$scope.msgtxt = "";
var fd = new FormData();
var imgBlob = dataURItoBlob($scope.myCroppedImage);
fd.append('clogo', imgBlob);
fd.append('actionfile', 'editimage');
$http.post(
'../user/user_EditCompany.php',
fd, {
transformRequest: angular.identity,
headers: {
'Content-Type': undefined
}
}
)
.success(function (response) {
// console.log(response);
if (response.status == 'success')
{
//your code
}else{
//your code
}
})
.error(function (response) {
console.log('error', response);
});
};
function dataURItoBlob(dataURI) {
var binary = atob(dataURI.split(',')[1]);
var mimeString = dataURI.split(',')[0].split(':')[1].split(';')[0];
var array = [];
for (var i = 0; i < binary.length; i++) {
array.push(binary.charCodeAt(i));
}
return new Blob([new Uint8Array(array)], {
type: mimeString
});
}
Thanks, the issue was caused by upload and post limit in my php.ini.
I'm using angular 1.2.27, and I'm trying to download a file. It works perfect on chrome but on FF nothing happens, the request returns 200/ok and the success code runs, but that's it, no file is downloaded:
var fileLoaded = $q.defer();
$http.get(url, { responseType: 'arraybuffer' })
.success(function (data,status,hdr) {
var cd = hdr('Content-Disposition').split(';');
var fileName = '';
_.forEach(cd,function(d){
if(d.trim().indexOf('filename') >= 0){
fileName = d.split('=')[1].replace(/[\"]/g,'');
return false;
}
});
var file = new Blob([data]);
var wurl = $window.URL || $window.webkitURL;
var fileURL = wurl.createObjectURL(file);
console.log( 'fileURL:' , fileURL );
var a = document.createElement("a");
a.href = fileURL;
a.download = fileName;
a.target = "_self";
document.body.appendChild(a);
a.click();
document.body.removeChild(a);
wurl.revokeObjectURL(fileURL);
fileLoaded.resolve(true);
}).error(function (data) {
// console.error(data);
fileLoaded.reject(data);
});
return fileLoaded.promise;
}
The only difference i see is when i log the fileURL. on chrome it appears like this:
blob:http%3A//localhost%3A9000/e869aa88-8190-4d9d-a379-9ad977a09613
And on FF like this:
blob:http://localhost:9000/f36b7773-00bb-4ade-87be-8f197c41ccf8
But I assume this is just a console thing.
any idea what I'm doing wrong?
Putting an answer here for reference. Using FileSaver from #Satpal comment, i was able to solve it easily:
var fileLoaded = $q.defer();
$http.get(url, { responseType: 'arraybuffer' })
.success(function (data,status,hdr) {
var cd = hdr('Content-Disposition').split(';');
var fileName = '';
_.forEach(cd,function(d){
if(d.trim().indexOf('filename') >= 0){
fileName = d.split('=')[1].replace(/[\"]/g,'');
return false;
}
});
var file = new Blob([data]);
saveAs(file, fileName);
fileLoaded.resolve(true);
}).error(function (data) {
// console.error(data);
fileLoaded.reject(data);
});
return fileLoaded.promise;
}
I need to write a javascript code for construct 2 plugin. below is my code :
Acts.prototype.PublishToWallPHOTO = function (snapshotdata)
{
if (this.runtime.isDomFree || !fbLoggedIn)
return;
var blob;
try
{
blob = dataURItoBlob(snapshotdata.replace("data:image/png;base64,", ""),'image/png');
}
catch(e){console.log(e);}
FB.api('/me/photos', 'POST', {
message:'photo description',
source:blob
}, function(response) {
if (!response || response.error)
console.error(response);
});
};
function dataURItoBlob(dataURI,mime)
{
var byteString = window.atob(dataURI);
var ia = new Uint8Array(byteString.length);
for (var i = 0; i < byteString.length; i++) {
ia[i] = byteString.charCodeAt(i);
}
var blob = new Blob([ia], { type: mime });
return blob;
}
for above code parameter for "snapshotdata" look like this : "data:image/png;base64,iVBORw0KGgoAAAA.........."
But my image was not uploaded to facebook using above code. but with same code if I use url:'http://example.com/abc.png' instead of source:blob then it upload a image in given URL successfully. I was tried to find the wrong with above code, but i was unable to find a proper solution. Please tell me if any one know the issue with above code.
ps: sorry for poor English
Maybe a FormData() does the trick.
function uploadPicture(response) {
if (response.status === 'connected') {
var blob = dataURItoBlob(imageHolder.imageElement.dom.src.replace("data:image/png;base64,", ""),'image/png');
var fd = new FormData();
var token = response.authResponse.accessToken;
fd.append("access_token",token);
fd.append("source\"; filename=\"" + "test.png" + "\"", blob);
fd.append("message","Test");
try{
$.ajax({
url:"https://graph.facebook.com/me/photos?access_token=" + token,
type:"POST",
data:fd,
processData:false,
contentType:false,
cache:false,
success:function(data){
console.log("success " + data);
},
error:function(shr,status,data){
console.log("error " + data + " Status " + shr.status);
},
complete:function(){
console.log("Ajax Complete");
}
});
}catch(e){console.log(e);}
}
}