How to open an S3 pre-signed URL in another tab? - javascript

How do I open an S3 file in another tab and not download it? I have this feature that generates a pre-signed URL. The front-end then opens this URL. However, what I would like to happen is to open the file in another tab so that the user can see the file before downloading it.
Backend
static async downloadFile(req, res, next) {
s3.getSignedUrl('getObject', {
Bucket: process.env.BUCKET_NAME,
Key: req.body.fileName
}, (error, url) => {
if (error) {
res.status(403).json({
err
})
} else {
res.status(200).json({
url
})
}
})
}
Frontend
User.downloadFile(fileName) // HTTP request was made in another file using axios
.then((res) => {
window.open(res.data.url)
})
Any advice is highly appreciated.

You need to set contentType of the image to the correct one while uploading the image to s3. like, set contentType to image/png if your image has .png format. If the contentType is not correct or not set then the image will be directly downloaded instead of displaying it in the browser. This should solve your problem.

Related

Google drive api file.get gives unreadable content

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.

NodeJS download file from AWS S3 Bucket

I'm trying to make an endpoint in NodeJS/Express for downloading content from my AWS S3 Bucket.
It works well, I can download the file in the client side but I can also see the stream preview in the Network tab which is annoying...
QUESTION
I'm wondering if what I'm doing is correct and a good practice.
Also would like to know if it's normal to see the output stream in the Network tab.
How should I properly send I file from S3 to my client application using NodeJS/Express?
I'm pretty sure other websites requests don't let you preview the content with a: "Fail to load response data".
This is what I do in my NodeJS application to get the stream file from AWS S3:
download(fileId) {
const fileObjectStream = app.s3
.getObject({
Key: fileId
})
.createReadStream();
this.res.set("Content-Type", "application/octet-stream");
this.res.set(
"Content-Disposition",
'attachment; filename="' + fileId + '"'
);
fileObjectStream.pipe(this.res);
}
And in the client side I can see this:
I think the issue is with the header :
//this line will set proper header for file and make it downloadable in client's browser
res.attachment(key);
// this will execute download
s3.getObject(bucketParams)
.createReadStream()
.pipe(res);
So code should be like this (This is what I am doing it in my project handling file as res.attachment or res.json in case of error so client can display error to end user) :
router.route("/downloadFile").get((req, res) => {
const query = req.query; //param from client
const key = query.key;//param from client
const bucketName = query.bucket//param from client
var bucketParams = {
Bucket: bucketName,
Key: key
};
//I assume you are using AWS SDK
s3 = new AWS.S3({ apiVersion: "2006-03-01" });
s3.getObject(bucketParams, function(err, data) {
if (err) {
// cannot get file, err = AWS error response,
// return json to client
return res.json({
success: false,
error: err
});
} else {
res.attachment(key); //sets correct header (fixes your issue )
//if all is fine, bucket and file exist, it will return file to client
s3.getObject(bucketParams)
.createReadStream()
.pipe(res);
}
});
});

download a file and pipe it to another upload url to different API

I have an image link that user can post to my app via form.
I need to download the file and make another API post request to another server.
app.post('/upload', async(req, res, next) => {
// image url is req.photo.url
const file = await require('request-promise')(req.photo.url); // i can get the response here
// now I need to post this file to another api
const options = {
method: post,
uri: 'http://sometesturl.com/api/upload',
body: {
file,
}
};
// but the file I am sending is not of type File and I am getting API error.
})
is there any way I can transform the file I downloaded into File type.
Any help would be highly appreciated. I have tried SO solutions but anything is not working.
Thanks in advance.

Node js serve file body from server and download in browser

I have a file repository and when i call it from the browser it automatically downloads the file and this is fine.
But i want to do this request on my server, and then serve the file result to the browser. Here is the example of the get request from my server.
downloadFile(req , res , next) {
let options = {
url: 'url to my file repo',
};
request(options, function (err, resp, body) {
if (err) {
res.status(500).send("");
return
}
for (const header in resp.headers) {
if (resp.headers.hasOwnProperty(header)) {
res.setHeader(header, resp.headers[header]);
}
}
resp.pipe(res);
})
}
The request is working fine, and when i access my server from the browser it starts downloading the file. Everything seems to work fine except one thing, the file can't be opened. This file format can't be opened, says me the image player (if the file is image for example).
Where is the problem, Is it the way i serve the file from the server?
Thank you in advance. I lost a lot of time and can't find the solution.
Because what you probably want to send is the body of the request (e.g. the data of your image).
So instead of resp.pipe(res):
res.send(body)
Use the developer mode of your browser to check the network messages passing between the server and your browser.

JavaScript Prompt download in browser

Im simply trying to download a file from the server and prompt the download in the browser for the user to see.
What i have right now:
Client
export function downloadTemplateAction(questionnaire) {
return dispatch => {
dispatch(downloadTemplateRequestAction(questionnaire));
return request
.get(downloadGETUrl)
.end((err, res) => {
if (err) {
console.log("Download ERROR", err)
dispatch(downloadTemplateFailureAction(err, questionnaire));
} else {
console.log("Download Success", res.body)
dispatch(downloadTemplateSuccessAction(res.body, questionnaire));
}
});
}
}
Server:
export function downloadTemplateDocument(req, res){
res.download('template/Example.docx');
res.end();
}
Im facing two problems:
First: When trying to download the file via the function of the Client, the response body is null but success and nothing more happens.
Second: When contacting the get API via the browser localhost:3002/api/download, the download works but the received file is empty. There should be text in it.
What am i doing wrong here?
Browser can't prompt a download progress because your request is sent via XMLHttpRequest.
Physical access to the file is needed for the browser to be aware of any download.
You could use download attribute to tell browser to download linked ressource.
original answer

Categories

Resources