Content of image not being displayed - javascript

I have a Blob of an image which I need to display in browser. The code provided below opens the image but shows some Mandarin scripts on the window.
Code:
var url="http://....link..../downloadFile?fdsFileId="+fileId;
$http({
method: 'GET',
url: url,
responseType: 'arraybuffer'
}).success(function (data, status, headers) {
headers = headers();
var contentType = headers['content-type'];
var blob = new Blob([data], { type: contentType });
var fileURL = window.URL.createObjectURL(blob);
console.log("url:"+fileURL);
console.log("content type:"+contentType);
window.open(fileURL);
window.URL.revokeObjectURL(fileURL);
The image displayed is as below:
The fileURL is provided in the browser.

set content-type : 'image/png' for png images and respectively for other files as well.
For all files support, set content-type : ''
Hope it helps.
Edit1:
setting content-type : '' did not work in chrome. Hence I had to extract the file extensions from the corresponding filename and then set the content-type using if-else.

Related

Return file from request framework7

I am trying to create a script for downloading files through a web app, for now I am concentrating on the script server then I will switch to cordova for phones.
Code i tried:
Javascript:
$f7.request({
method: 'POST',
url: urlofwebsite + 'api/getFile.php',
crossDomain: true,
data: {
fakeid: idoffile,
iduser: iduser, // check for security reason
time: timeoflogin // check for security reason
},
success: function(data, status, xhr) {
var blob = new Blob([data], {
type: 'application/pdf'
});
var url = window.URL.createObjectURL(blob);
var fileName = 'test.pdf';
var urllink = url;
var link = document.createElement('a');
link.href = urllink;
link.download = fileName;
link.click();
}
});
PHP:
$file = $_SERVER['DOCUMENT_ROOT'].$res['url'];
readfile($file);
By manually specifying the extension and file type (just for test it), the file from the blob is downloaded but completely blank.
thanks to #ADyson for help, i can provide a community wiki answer:
Besides the various basic problems such as header etc. in my question, there was a fundamental trick which is adding this command to the request:
xhrFields: { responseType: 'blob' }
In the php file instead just use:
$file = PATHTOFILE; readfile($file);

PDF File download from AJAX Post success callback

When I try to link to a data-generated file that I've set up to be rendered as a PDF document, this works to open a PDF document in a new window, but only for small sets of data:
window.open(myUrl + params, "_blank", "menubar=no,status=no");
I need it to work for something like this so I can make my PDF compatible with larger data sets. I tried passing the params in the data section of the ajax request but it doesn't work for PDF documents only. It works for Word and Excel documents. When I try the same thing as a PDF, it returns a download to a broken PDF object.
$.ajax({
type:"POST",
async:true,
url: myUrl,
data: params,
success: function(result,status,jqhxr) {
var blob=new Blob([result]);
var link=document.createElement('a');
link.setAttribute('target','_blank');
link.href=window.URL.createObjectURL(blob);
link.download="PreviewProposalAsPdf.pdf";
link.click();
}
});
What do I need to do to get this to render a PDF correctly? Ideally I'd like to navigate directly to the PDF page in a new window, but I will settle for a clickable file download. Please post the full solution directly if possible. I've spent a ton of time on this and my time is now running short.
I looked for the solution on other questions but none of the solutions worked. In some cases, what I'm already trying was posted as a solution. Please help.
Thanks
The result you get back from using jQuery ajax is plain text and can lead to "out of range" for downloading binary as text and not as arrayBuffer or blob. jQuery don't support responseType in any way (that i know of)
So you need to rely on xhr or fetch to get it as a blob to get the content right. Otherwise you will get corrupt data
Here is an example of using the new fetch api and FileSaver
function saveAs(blob, filename){
if(navigator.msSaveOrOpenBlob)
return navigator.msSaveOrOpenBlob(blob, filename)
var link = document.createElement('a')
link.href = window.URL.createObjectURL(blob)
link.download = filename
link.click()
}
fetch(myUrl, {
method: 'post',
body: JSON.stringify(params)
headers: {
'Content-Type': 'application/json;charset=UTF-8'
}
})
.then(res => res.blob())
.then(blob => saveAs(blob, 'PreviewProposalAsPdf.pdf'))
// EXAMPLE USING XHR
var req = new XMLHttpRequest
req.open('GET', myUrl, true)
req.responseType = 'blob'
req.onload = function() {
saveAs(res.response, 'Dossier_' + new Date() + '.pdf')
}
req.setRequestHeader('Content-Type', 'application/json;charset=UTF-8');
req.send(JSON.stringify(params))
But ofc, there is more wider support if you use xhr + responseType = blob
The best thing you can do is just send content-disposition header and make a attachment - but then you can not use ajax... need to submit form (could be from iframe)
Another solution using $.ajax & FileSaver
I think the xhrFields should be the answer you look for...
$.ajax({
type: "POST",
url: "your-url/to/pdf/response",
data: params,
xhrFields: {
responseType: 'blob' // without this, you will get blank pdf!
},
}).done( function(res) {
blob = new Blob([res], { type: 'application/pdf' })
saveAs(blob, "response.pdf")
}).fail( function() {
alert("Error! Please try again later...");
});
This is the correct answer, without using the SaveAs function:
var req = new XMLHttpRequest();
req.open("POST", myUrl, true);
req.responseType = "blob";
req.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
req.send(data);
req.onreadystatechange = function() {//Call a function when the state changes.
if(req.readyState == 4 && req.status == 200) {
console.log(req.responseText);
}
}
req.onload = function (event) {
var blob = req.response;
console.log(blob.size);
var link=document.createElement('a');
link.href=window.URL.createObjectURL(blob);
link.download="Dossier_" + new Date() + ".pdf";
link.click();
};
Ultimately it solved my problem. Thank you, Endless.

Base64 is too large to open in a browser, any alternatives?

My base64 PDF is too large that when I try and open it in a window, the url isn't pasted. I then substring'd it and the link would paste but of course.. it doesn't open as it hasn't received the whole base64.
Code:
$.ajax({
url: [database-url-here],
type: 'GET',
dataType: 'json',
success: function(data){
var pdf = (data.pdf).toString();
window.open(pdf);
}
});
var w = window.open('', '', 'width=400,height=240'); // open blank page
w.document.write(
'<embed type="application/pdf" ' +
'width="400" height="240" ' +
'src="data:application/pdf;base64,' + pdf + '">'
);
For too big base64 pdf files I convert it to blob and then create a new URL from that blob.
Blob URL is much smaller then base64 url.
To convert I do something like this:
var url = 'data:application/pdf;base64,'+ base64string;
var blobUrl;
fetch(URL)
.then(res => res.blob())
.then(URL.createObjectURL)
.then((ret) => {blobUrl=ret; return blobUrl;})
.then(console.log)
One can test at this jsfiddle at example 2.
Or see other alternatives here

SharePoint Online REST - Image upload via JavaScript/AJAX

I'm trying to upload an image to SharePoint using native JavaScript/jQuery - NOT SP.RequestExecutor.
I've cracked the authentication issue, nice and easy, so now it's just a case of working out how to upload binary files. If I put plain text in the file, it uploads fine, it's just binary data I'm having trouble with.
My code so far is included below. getToken() does it's thing and leaves me with a valid digest object to use. Also note I've blanked out the document library name with *'s.
function PerformUpload(fileName, fileData) {
getToken();
$.ajax({
url: siteFullUrl +
"/_api/web/GetFolderByServerRelativeUrl('/*****/')/Files" +
"/Add(url='" + fileName + "', overwrite=true)",
type: "POST",
async: false,
data: fileData,
processData: false,
contentType: "application/json;odata=verbose",
headers: {
"Accept": "application/json;odata=verbose",
"X-RequestDigest": digest
},
success: function (data) {
alert("Success");
},
error: function (err) {
alert("Error: \r\n" + JSON.stringify(err));
}
});
}
I've tried many combinations of different values for contentType, setting binaryStringRequestBody: true but the image is still corrupt when it comes into SharePoint.
My code at the moment to parse the file into binary is
var reader = new FileReader();
reader.onload = function (result) {
var fileName = '',
libraryName = '',
fileData = '';
var byteArray = new Uint8Array(result.target.result)
for (var i = 0; i < byteArray.byteLength; i++) {
fileData += String.fromCharCode(byteArray[i])
}
PerformUpload("image.jpg", fileData);
};
reader.readAsArrayBuffer(fileInput);
A file is being uploaded to SharePoint but if I try and view or download it it's corrupt.
Can anyone provide any guidance as to the correct way to upload a binary file to SharePoint? I should mention that if I replace (on the ajax call) data: fileData, with data: "A simple string", the file uploads and when I download it the contents of the file are A simple string.
If you are using SP.RequestExecutor to upload the file to SharePoint, you must be converted the ArrayBuffer into a string which can then be set as the body of a POST operation. See details here which guide you how to Upload file to SharePoint using REST by SP.RequestExecutor.
If you are using parsed file into binary with Jquery.Ajax, the image will corrupt when it comes into SharePoint. Also noted that the FileReader object accepts the file information for loading asynchronously. The onload and onerror events fire when the file is loaded successfully or fails. We should keep the proccess of onload event by default and get the result in onloadend event.
I tried the following articles and it work:
How to: Upload a file by using the REST API and jQuery
For simple, here is how I implemented:
var fileInput = jQuery('#getFile');
var file = fileInput[0].files[0];
var serverRelativeUrlToFolder = '*****'; //if the library in subsite, You have to remove the forward slash "/" before the document library relative url.
proccessUploadUsingJQueryAjax(file, serverRelativeUrlToFolder);
function getFileBuffer(file) {
var deferred = jQuery.Deferred();
var reader = new FileReader();
reader.onloadend = function (e) {
deferred.resolve(e.target.result);
}
reader.onerror = function (e) {
deferred.reject(e.target.error);
}
reader.readAsArrayBuffer(file);
return deferred.promise();
}
function addFileToFolderUsingJQueryAjax(fileName, arrayBuffer, serverRelativeUrlToFolder) {
// Construct the endpoint.
var fileCollectionEndpoint = String.format(
"{0}/_api/web/GetFolderByServerRelativeUrl('{1}')/files/add(overwrite=true, url='{2}')",
_spPageContextInfo.webAbsoluteUrl, serverRelativeUrlToFolder, fileName);
// Send the request and return the response.
// This call returns the SharePoint file.
return jQuery.ajax({
url: fileCollectionEndpoint,
type: "POST",
data: arrayBuffer,
processData: false,
contentType: "application/json;odata=verbose",
headers: {
"accept": "application/json;odata=verbose",
"X-RequestDigest": jQuery("#__REQUESTDIGEST").val()
}
});
}
function proccessUploadUsingJQueryAjax(file, serverRelativeUrlToFolder){
var getFile = getFileBuffer(file);
getFile.done(function (arrayBuffer) {
// Add the file to the SharePoint folder.
var addFile = addFileToFolderUsingJQueryAjax("image.jpg", arrayBuffer, serverRelativeUrlToFolder);
addFile.done(function (file, status, xhr) {
alert("File Uploaded");
});
addFile.fail(function (error) { alert("Error Add File: " + error.responseText); });
});
getFile.fail(function (error) { alert("Error Get File: " + error.responseText); });
}
Please let me know if it solved your problem.
Try adding this to your ajax settings
transformRequest: []
this will prevent Sharepoint from adding metadata to your file

$.ajax not working in IE9

I have the following code that is working on Chrome and Firefox, but not in IE9
$.ajax({
type : type,
url : url,
data : reqData,
crossDomain: true,
cache: false,
dataType : dataType,
contentType : contentType,
success : successFunction
}).fail(function() {
showError("IE9!");
});
type is POST, dataType is JSON and contentType is application/json
All the other parameters are correct
I've tried removing the contentType, removing the cache, setting cache to true, nothing seems to work
Any thoughts?
Thanks in advance
you cannot use normal ajax for cross domain access in ie, you have to use XDR for this purpose
please refer this link
Check the url path ( should be absolute ) and make it unique adding a timestamp for example
var url = 'http://mydomain.com/' ** not '/' **
var timestamp = new Date()
var uniqueUrl = url + (uri.indexOf("?") > 0 ? "&" : "?") + "timestamp=" + timestamp.getTime()
then
url : uniqueUrl,

Categories

Resources