Displaying private S3 images in node express app - node.js

I am developing a node express web application and I am trying to figure out how to display private s3 images when performing a query or single request for an image to views for proper html rendering. I've looked around and didn't find enough information to fully wrap my head around this.
To reiterate, I cannot publicly host them. They have to be privately stored and retrieved when a user uses my express app. I've tried knox which is great for piping, but I don't know how to display all images in one go to a query results page for example. Or more importantly, how to show the raw image data recieved from knox. I also read some stuff about Amazon CloudFront and all that stuff, but would like to exhaust some closer options than doing more and more configuration.
So, how can I view these private s3 images from an express web app? More specifically, displaying a collection of images or a single image.

So if your goal is to have the server fetch the images and then send them to the client, it looks like knox should be able to help you:
from their Github page, with tweaks:
app.get('/img/:filename', function(req, res){
client.getFile('/whatever/' + req.query.filename, function(err, s3res){
s3res.pipe(res)
});
}
Note: untested.

Related

Serving an image from Node.js to React (how does the frontend part work?)

I know there are a lot of similar posts out there yet after reading as many as I could find I am still left with questions.
I have a site set up with a node server running on port 5000 and React running on port 3000. I am using multer to upload user selected images from the front end and save them in the file system on the node backend side, which works perfectly fine.
My trouble lies in trying to get those same images and serve them back to the react front end to render on page. I have tried using express.static() to serve the images as several folks talk about doing but when I do so I don't know how to actually access those images from the front end, I couldn't find anyone talking about that part. When trying to access by the relative path from the front end I recieve net::ERR_BLOCKED_BY_RESPONSE.NotSameOrigin 200
My very rudimentary backend code:
router.get("/retrieve/:id", async(req,res) => {
const pathname = path.join(__dirname,"../userProjects/project_ted/photos/test.jpg")
app.use(express.static(pathname));
res.send(200);}
So my questions are:
Am I doing something fundamentally wrong here with having my front and back end running on two different ports and attempting to send a picture from the node side to the react side with express?
If I am not then what does the front end code look like to render a picture served from express?
To be clear I don't want to download the photo, I want to display it on the page.
Thanks in advance!
First, the app.use() is misplaced. It shouldn't be in a route callback.
As far as I understand you're trying to send a test image to all requests. If so, you can use Express' sendFile method for that:
router.get("/retrieve/:id", (req, res) => {
const pathname = path.join(__dirname,"../userProjects/project_ted/photos/test.jpg")
res.sendFile(pathname);
});
To access the image directly from the fronted do
<img src={'http://localhost:5000/userProjects/project_ted/photos/test.jpg'} alt="" />
This worked for me.

Is it more efficient for severs to send an image file or a path to an image file to the client?

I'm using express js to serve files to an angular app and I'm deciding between these approaches:
res.status(201).json({ imagepath: '<URL>' });
res.sendFile('<URL>');
I'm thinking that sending the url will force an extra round trip so I should go with the sendFile but I want to doublecheck. Is there anything I'm missing?
The best option would be to store the image file on something like AWS S3 and then send the file URL using your Express application. You would use the aws-sdk package here to save the image to S3 (detailed article here). Then you would send the URL location of that image to your database to be stored.

How can update static files in node js app?

I have nodejs app using express module, i had been changes some images inside public folder but when i checked from users side still on the old images and when clear browser cache i get on new images , is there a command to make this automatically.
Have a look at Etag. If the content of the resource is not changed the server will not send it again. When it is, as in your case it will.
Looking at the express docs I see etag is an boolean option of the middleware function static.
express.static({etag: true})
Some background information about tags.
https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/ETag

How to accept a file and then store it in cloud storage

I am using expressjs (all newest versions of express, node, and npm). I have create a route such as this:
router.post("/", function(req, res, next) {
});
This route will need to be able to have a file (image/video/docx,etc) uploaded and needs to then be stored on a cloud storage service (Google Storage). I do not want to store anything on the server that express is running on, just want to receive the file and pass it on over to Google Cloud Storage. I see there are some libraries which do this in addition to express, but I couldn't not find how to do it using just express.
I think your clients might be able to upload directly to GCS by constructing a HTML form. Basically you can create a signed url and embed it in the form and then on submit, the upload goes straight to GCS and your app doesn't need to handle it at all.
See: https://cloud.google.com/storage/docs/xml-api/post-object

Node.js works with CouchDB and Backbone.js, How json is being served?

I am trying to build a test app for learning Node.js. I came from wordpress background and Apache has setup most of backend logics for me. But now, I have to build my own. I have a question about how to serve JSON files from server side to client side. What is the workflow -- Backbone.js handle all client side Data manipulation, send/save/get/fetch from couchDB, serve JSON object from NODE.js backend?
I am using Express Microframework for building HTTP server, installed the Cradle middleware for access CouchDB NoSQL database. I successfully posted the data from Client side HTML (Jade template engine) to the CouchDB Database/Document and able to retrieve those data back from Server through Cradle middleware. Things work out great. But it was all done by Backend.
I want to use Backbone.js for my client side Javascript. Backbone.js is looking for JSON object which send back from the HTTP server. Cradle Middleware is able to create JSON object but only send them directly to the Jade Template, I could use Jade syntax for loop to iterate over the data object but it still not meet what I want for Backbone.js handle all the data entry. I realize that I need to get JSON obj via ajax ( either a file generated by HTTP then send back to the client OR send straight object to the client ). Cradle Middleware could not do that.
I did more research on this questions. I tried CouchApp, it does what I need. Using the Backbone.js to handling all the data, send/save/fetch data from CouchDB database. But it is a running in CouchApp, it is not an Express Node.js workflow. ( Maybe I am wrong or just do not how it work )
I tried backbone-couchdb.js. I read through the Details and still do not know it is going to help me to get what I want. ( Maybe need more tutorial or code example ). I am still thinking that I need a Backbone CouchDB driver to connect those two and somehow serving them by NODE.js backend.
Is there anybody who could tell me about how JSON file is being served by Node.js, how backbone.js interact with data save/fetch/get from CouchDB? What is the best practice / workflow? Other good resources, code examples, useful tools?
Cradle Middleware is able to create JSON object but only send them directly to the Jade Template
This is incorrect. You can just send the json back without rendering a template.
function(req, res, next){
db.view('user/byUsername', { key: 'luke' }, function (err, doc) {
res.send(doc); // or res.json(doc);
});
}

Resources