Google drive api file.get gives unreadable content - javascript

I just need to read the content of a file(no need to download the file) and store the data into my application. I am able to get the content of a file in response by using this api "https://www.googleapis.com/drive/v3/files/fileId?alt=media". But the response of this api returns an unreadble format, something like this "�dҚ�ȳ:\u0010��$���2�m��L̆���✳ŝ-�lqg�;[����O�s�\u0011�\u001bk\".
Below is the code I am using. This is Gdrive api v3.
drive.files.get(
{
fileId: fileId,
alt: "media",
},
(err, res) => {
if (err) {
console.log("err = ", err);
return false;
}
if (res) {
console.log("File Details");
console.log(res);
}
}
);
How can I get the data in readable format?

Based on your comment:
I used the below api , it gave the actual content in response itself
The key in that particular request is that the file mimeType is:
mimeType: "text/plain"
This means that the content of this file is just text, so you can read the contents no problem.
However, it looks like in your original question you are requesting a file that is not plain text. Maybe a PDF, or a Word .doc. These files are encoded in binary so their content is not readable by humans. To read the contents you need the appropriate program.
Though you haven't provided the full code, so I can't be sure what type of file you are trying to download.

Related

Downloading a zip file from a given path in express api + react

So I'm completely lost at this point. I have had a mixture of success and failure but I can't for the life of me get this working. So I'm building up a zip file and storing it in a folder structure that's based on uploadRequestIds and that all works fine. I'm fairly new to the node but all I want is to take the file that was built up which is completely valid and works if you open it once it's been constructed in the backend and then send that on to the client.
const prepareRequestForDownload = (dirToStoreRequestData, requestId) => {
const output = fs.createWriteStream(dirToStoreRequestData + `/Content-${requestId}.zip`);
const zip = archiver('zip', { zlib: { level: 9 } });
output.on('close', () => { console.log('archiver has been finalized.'); });
zip.on('error', (err) => { throw err; });
zip.pipe(output);
zip.directory(dirToStoreRequestData, false);
zip.finalize();
}
This is My function that builds up a zip file from all the files in a given directory and then stores it in said directory.
all I thought I would need to do is set some headers to have an attachment disposition type and create a read stream of the zip file into the res.send function and then react would be able to save the content. but that just doesn't seem to be the case. How should this be handled on both the API side from reading the zip and sending to the react side of receiving the response and the file auto-downloading/requesting a user saves the file.
This is what the temp structure looks like
There is some strategies to resolve it, all browser when you redirect to URL where extension ending with .zip, normally start downloading. What you can do is to return to your client the path for download something like that.
http://api.site.com.br/my-file.zip
and then you can use:
window.open('URL here','_blank')

How to read PDF files with Node.js without using third-party library?

I'm trying to read the content of a PDF document using Node.js fs.readFile method, but I'm getting some weird characters in the response.
fs.readFile(directory + '/' + pdf, 'binary', (err, data) => {
if (err) {
console.log('Unable to read PDF: ' + err);
}
console.log('PDF content:', data);
});
Is there a specific encoding type that could be used to return the text content of a PDF document without using a third party library?
A PDF file is not plaintext.
If you want to read it, you might want to check this: https://en.wikipedia.org/wiki/PDF#File_structure

Sending a file to the client from Node.js with Express

I have a unique situation in terms of difficulty.
I need to send HTML to the server, have the server convert the HTML to a PDF, send that PDF back to the client, and then download the PDF using client-side code.
I have to do it this way because I'm using client-side routing, so the only way I can access my endpoint that should perform this action is via a GET Request with Ajax or Fetch from client-side JavaScript. I am aware of res.sendFile(), but that attempts to render the file in the browser - I don't want that - rather, I want to be able to use client-side code to download the file.
Is it possible, then, to send a PDF file from temporary storage on the server down to the client, allowing client-side code to do whatever it wants to the file thereafter - in my case, downloading it?
I don't believe I have to provide any code because this is more of a theoretical question.
My issue stemmed from the fact that I could not just use res.sendFile() or res.download() from Express because the route was not being accessed by the browser URL bar, rather, my application uses client-side routing, and thus I had to make an HTTP GET Request via Fetch or XMLHttpRequest.
The second issue is that I needed to build the PDF file on the server based on an HTML string sent from the client - so again, I need to make a GET Request sending along a request body.
My solution, then, using Fetch, was to make the Get Request from the client:
fetch('/route' , {
method: 'GET',
body: 'My HTML String'
});
On the server, I have my code that converts the HTML string to a PDF, using the HTML-PDF Node module, and then, I convert that file to a Base64 String, setting the MIME Type and appending data:application/pdf;base64,.
app.get('/route', (req, res) => {
// Use req.body to build and save PDF to temp storage (os.tempdir())
// ...
fs.readFile('./myPDF.pdf', (err, data) => {
if (err) res.status(500).send(err);
res.contentType('application/pdf')
.send(`data:application/pdf;base64,${new Buffer.from(data).toString('base64')}`);
});
});
Back on the client, I have my aforementioned Fetch Request, meaning I just need to tack on the promise to get the response:
fetch('/route', {
method: 'POST',
body: 'My HTML String' // Would define object and stringify.
})
.then(res => res.text())
.then(base64String => {
// Now I just need to download the base64String as a PDF.
});
To make the download, I dynamically create an anchor tag, set its href attribute to the Base64 String in the response from the server, give it a title, and then programmatically click it:
const anchorTag = document.createElement('a');
anchorTag.href = base64String;
anchorTag.download = "My PDF File.pdf";
anchorTag.click();
So, all together and on the client:
fetch('/route', {
method: 'POST',
body: 'My HTML String' // Would define object and stringify.
})
.then(res => res.text())
.then(base64String => {
const anchorTag = document.createElement('a');
anchorTag.href = base64String;
anchorTag.download = "My PDF File.pdf";
anchorTag.click();
});
The solution for using an anchor tag to trigger the download came from another StackOverflow answer. It's also important to note that Base64 Encoding is not very efficient. Better solutions exist, but for my purposes, Base64 will work fine.
It is also imperative to note that Base64 Encoding is precisely that - an Encoding Scheme, not, I repeat, not an Encryption Scheme. So if your PDF files contain privileged information, you would likely want to add token authentication to the endpoint and encrypt the file.

Store Image file in Binary data in mongoose schema and Display image in html form

I am using Express, Node.js, and Mongodb to create the webpage that uploads and displays the image file.
I saved the binary of image in mongodb using schema.
Here is my little bit of code in index.js and db.js..
var Post = mongoose.Schema({
image: {data: Buffer, contentType: String}
});
var post= new Post({ });
post.image.data=fs.readFileSync(req.file.path);
post.image.contentType='image/png';
and here is the part of mongo shell after I submitted image file and searched for post, and its image field
"image: {"data:BinData(0,"iVBORw0KGgoAAAANSUhEUE....(I
just cut off the rest of the code.. cuz it was too long)
rkJggg=="),
"contentType" : "image/png" }
so it seemed like it's successfully saving the binary data of image file in mogngodb,
but my problem is how to display the image on the webpage now using binary data. How do I convert binary buffer data to create image tag??
<img src= "data:{{image.contentType}};base64,{{image.data}}">
I tried this, but it gives me an error:
Failed to load resource: net::ERR_INVALID_URL
Could you guys please let me know how do I solve this??
I will really appreciate for your help :(((
First of all, you have to convert buffer data to base64. You can do it in back-end or front-end it does not matter. Just use yourBufferData.toString('base64'). Then you can use it.
However, I would suggest another way to store images instead of storing binary data. Assuming you use nodejs. You can create image in a repository with that binary data using fs.writeFile method. Then you can store that image path in record (db). AFter that, just put the file path into ng-src="file path which you saved". Here is the example which I use:
var path = 'upload/profiles/' +req.body.userId + '_profile.jpg';
fs.writeFile(path, base64data, function(err) {
if (err) return next(err);
User.findByIdAndUpdate({
_id: req.body.userId
}, {
$set: {
profileImg: 'upload/profiles/' +req.body.userId + '_profile.jpg'
}
}, function(err, user) {
if (err) return next(err);
return res.send(user);
});
});
<img ng-src="savedpath">

Download Csv file on front end after clicking on button using angularjs , nodejs ,expressjs

I want to download .csv file on frontend.
this is my code:
$http.get('/entity/consultations/_/registerationReport' )
.success(function (data) {
myWindow = window.open('../entity/consultations/_/registerationReport', '_parent');
myWindow.close();
});
and I use json2csv converter to write in csv file.
json2csv({data: report, fields: fields}, function (err, csv) {
if (err) throw err;
res.setHeader('Content-Type', 'application/csv');
res.setHeader("Content-Disposition", "attachment; filename=" + "Report.csv");
res.end(csv, 'binary');
});
but it prints data of csv file on browser instead of downloading csv file.
#Pawan, there's nothing wrong with your json2csv function. The issue is the fact that you're trying to trigger the download with an XMLHttpRequest (XHR) request using Angular's $http service. An XHR call suggests that your code will be handling the response from the server. As such the Content-Disposition headers are ignored by the browser and do not trigger a download on the browser.
From what I can tell you have several options:
If you don't have any pre-processing to do on the client, why not just use a direct link to /entity/consultations/_/registerationReport (using and <a> tag),
You may also write $window.open(...) from your Angular code (this will have the ugly side effect of a flashing popup tab or window)
There are probably a number of other solutions, but these are the only ones that immediately come to mind. The bottom line is that XHR is not the right tool for the task you're trying to accomplish.

Categories

Resources