Return file from request framework7 - javascript

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);

Related

php javascript download .gz file ajax

In my project I am using Symfony 3 + Filesaver.js and I need to download a .gz file. I do ajax request to my server with the following code:
function requestAjax(json_data) {
var request = $.ajax({
url: '/ajax'
, method: 'post'
, data: json_data
});
return request;
}
var json_text = {'type': 'download_file'};
var request = requestAjax(json_text);
request.done(function (response) {
var blob = new Blob(
[response], {
type: "text/plain;charset=" + document.characterSet});
saveAs(blob, 'filename.gz');
});
On php side I do the following:
$myfile = '/opt/myfile.gz';
$fp = fopen($myfile, "rb");
$response = base64_encode(fread($fp, filesize($myfile)));
fclose($fp);
return new Response($response);
But when I try to open my downloaded file, I get an error that the file is broken and cannot be read (still I can read it on my server and I know that the file is ok). So the question is how to download a .gz file with an ajax call in php + javascript. Thank you.

Content of image not being displayed

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.

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.

How to handle the forced download of zip file using JQuery

I'm using a REST API with POST data. I'm creating a zip file and doing a forced download. I need to call that API by sending the required POST data using JQuery, which should then get the download. How can I achieve this?
You could do this :
HTML:
<input type="button" class="list" value="Download ZipFile" id="download"/>
JS :
$("#download").click(function(){
//this is the data when you send your request
var data = { yourKey1 :'something1', yourKey2:'something2'};
// this is a fake response that we are assumming you got from ajax's response inside success call back
var response = {fileName:'yourFileName.zip' ,filePath : 'YouFilePath'};
$.ajax({
type: "POST",
url: 'yourURL',
data: data,
success: function(response) {
download(response);
}
});
});
var download = function (data){
var link = document.createElement('a');
link.href = data.filePath + data.fileName ;
//below you can define a new name
link.download = data.fileName;
document.body.appendChild(link);
link.click();
}
Example : https://jsfiddle.net/3yjt4Lah/8/

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

Categories

Resources