show image which is served by express in nodejs - node.js

I serve image from local hard drive in node express using sendfile like :
app.get('/data/getImage/:Id', function (req, res) {
console.log(req.params.Id);
res.sendfile('C:\\defaultimg.png', function(error){
if(error)
console.log(error.message);
else
console.log('File transferd successfully.');
})
});
and I call this method in angular and get data like:
var resource = $resource('/data/getImage/:id', {id: '#id'}, {getImage: {method: 'GET', isArray: false}});
resource.get({id: _id}, function (image) {
console.log('getImageById');
console.log(image);
callback(image);
});
so, my question is how i can i show this received data in image tag ?
thanks

Save the image path some where on your scope and then use ng-src.
<img ng-src="{{scopePropertyWithImageUrl}}" />
Link to the documentation: ng-src.

Related

Node Express "favicon.ico" not found error

I'm trying to download a photo through a URL passed as a query string using Express, but every time I try to use it, I get Error: Invalid URI "favicon.ico" Is there a way I can get my browser to stop requesting a favicon? For downloading images, I'm using the image-downloader package (NPM page)
Code:
app.get('/:url', (req, res) => {
let url = req.params.url;
const options = {
url: url,
dest: /path'
};
download.image(options)
.then(({ filename, image }) => {
console.log('File saved to ', filename);
})
.catch((err) => {
console.log(err);
});
res.send("Done");
});
It's probably easiest to just make a route for favicon.ico in your server.
app.get('/favico.ico', (req, res) => {
res.sendStatus(404);
});
Of course, you could actually send a valid icon too if you wanted, but this will at least keep your Express server from showing an error.
FYI, this has nothing to do with the image-downloader. This has to do with the browser requesting a favico.ico icon that it uses to show in the URL bar (and some other places in the browser UI). If your server returns a 404 for favicon.ico, the browser will use a generic icon in its UI.
If you want to make yourself a simple favico.ico, you can go here and it will help you generate one and then you can change the above route to:
app.get('/favico.ico', (req, res) => {
res.sendFile("myfavico.ico");
});
Try using another package like request module. I believe it got this type of things handled.
var fs = require('fs'),
request = require('request');
var download = function(uri, filename, callback){
request.head(uri, function(err, res, body){
console.log('content-type:', res.headers['content-type']);
console.log('content-length:', res.headers['content-length']);
request(uri).pipe(fs.createWriteStream(filename)).on('close', callback);
});
};
download('https://www.google.com/images/srpr/logo3w.png', 'google.png', function(){
console.log('done');
});

Vuejs load image from nodejs res.sendFile

In my vue's created, I use axios to connect to my server to retrieve an image as below:
created() {
this.schoolID = localStorage.getItem('schoolID')
console.log(this.schoolID)
axios.get(process.env.MY_URL + '/public/logo', {
params: {
schoolID: this.schoolID
}
})
.then(response => {
this.logo = response.data
console.log(this.logo)
})
.catch(e => {
console.log(e.response)
this.errors.push(e)
})
},
and my nodejs will receive the request and send the response like below
router.get('/logo', function(req, res){
School.findOne({ _id: mongoose.mongo.ObjectId(req.query.schoolID) }).exec().then(function (data) {
if (!data){
console.log("error... no logo found for the given id: " + req.query.schoolID)
return res.status(200).send({success: false, msg: 'No logo found.'});
}else{
res.sendFile(__dirname + '/uploads/' + data.logo);
}
});
});
my image should be loaded into my code
<img :src="this.logo">
I'm positive I got (at least the nodejs) the image file correctly because if I just append some string at the end of data.logo, I will get 404 not found error in my Vue and ENOENT: no such file or directory, stat 'D:\web\musleh-api\uploads\1542208727664_logo_sdam.png' error in my nodejs
However, no image is being loaded,and my console.log(this.logo) will display funny symbols which I assume is the image file if we try to open it using any text editor.
What did I miss?
I believe what you need to do is this in your HTML code, assuming that your image is base64 encoded:
<img alt="Awesome logo" :src="'data:image/png;base64,'+this.logo" />
Here is the source
Addition, as above seems not to work:
After some research I think we are not completely on the wrong path here, but give this a try:
On the NodeJS side try this:
}else{
var img = fs.readFile('__dirname + '/uploads/' + data.logo', function (err, data) {
var contentType = 'image/png';
var base64 = Buffer.from(data).toString('base64');
base64='data:image/png;base64,'+base64;
res.send(base64);
});
});
});
then in VueJS as before:
<img alt="Awesome logo" :src="this.logo" />
OR THE EASY WAY:
On the NodeJS side try this:
}else{
// prefix your domain if your API serves to other domains
res.send('/uploads/' + data.logo');
});
});
});
Also here Vuejs code remains as you did it.
Assuming that you want to pass the school ID to request the image, you don't need axios to make the request, you can use directly the <img src> tag with a dynamic parameter to request the data. You also need to change you express configuration to return the image with Content-Type:'image/png' or whatever is the mime type of your data.
Then on vue template you will need to pass the school id to the dynamic route, the data request and handling will be done by the img element
<img :src="`/logo/${schoolID}">
.
router.get('/logo/:schoolID', function(req, res){
School.findOne({ _id: mongoose.mongo.ObjectId(req.params.schoolID) }).exec().then(function (data) {
if (!data){
console.log("error... no logo found for the given id: " + req.params.schoolID)
return res.status(200)
.send({success: false, msg: 'No logo found.'});
}else{
res.type('png')
.sendFile(__dirname + '/uploads/' + data.logo);
}
});
});

can't pass data in to delete request with Vue-Resource

im getting problem with passing data in to delete request with Vue-resource. Server is reciving blank object without data. There is some code:
Front-end with Vue.js and Vue-resourcer
deleteArticle: function(tit){
console.log(tit);
this.$http.delete('http://192.168.0.52:8080/article',{'title':'123'}).then((res)=>{
this.refresh();
console.log(res.data);
}).catch((e)=>{console.log(e)});
}
Back-end with node.js route using express.js API.
app.delete('/article', (req,res)=>{
var body = _.pick(req.body,['title']);
console.log(req.body); //printing blank object from request
Article.findByTitleAndRemove(body.title).then((doc)=>{
res.status(200).send(`Deleted Article with title ${doc.title}`)
}).catch((e)=>{
console.log(e);
res.status(400).send(e);
})
})
This route works with postman.
Try this:
this.$http.delete('http://192.168.0.52:8080/article', { params: { title: 123 } }).then(res => {
this.refresh();
console.log(res.data);
}).catch((e)=>{console.log(e)});
Update: this is how this works for me in node:
app.delete('/article', (req, res) => {
console.log(req.query.title);
});

Saving HTTP GET response to a file in a express/node app

I have an express/node app which exposes a GET end point via express router something like /api/user. The response is a JSON and i want to download the JSON to a file when i hit localhost:8080/api/user.
I tried with res.download but not sure how to handle the response data with it. This could be a duplicate question but i cannot find an example especially for this use case.
When the end point is invoked in browser it should prompt for download and then should get downloaded to the default location.
router.route('/user')
.get((req, res) => {
MyService.get().then((result) => { // the get method resolves a promise with the data
// Prompt for download
}).catch((err) => {
console.log(err);
res.status(500).json({
status: 500,
data: err
});
});
});
So i was able to do this in one of the 2 ways below,
router.route('/user')
.get((req, res) => {
MyService.get().then((result) => {
res.attachment('users.csv');
/*or you can use
res.setHeader('Content-disposition', 'attachment; filename=users.csv');
res.set('Content-Type', 'text/csv');*/
res.status(200).send(result);
}).catch((err) => {
console.log(err);
res.status(500).json({
status: 500,
data: err
});
});
});
If I understand correctly, you want to save the sent data of /api/user to a file that you are sending in a route?
var fs = require('fs')
app.get("/api/user", function(req, res){
var data = fromDb()
fs.writeFileSync("/tmp/test", JSON.stringify(data))
res.send(data)
})
You need to write the JSON response to a file using the node filesystem module. You can check out an example here Writing files in Node.js
If I got you right then You can try Content-Type and Content-disposition headers like below:
res.writeHead(200, {'Content-Type': 'application/force-download','Content-disposition':attachment; filename={your_file_name}.json});
res.end(data);
NOTE :
data in res.end(data) is your json data.
{your_file_name}.json is your actual file name , give it any name.

NodeJs: Sending picture with Express (Multer)

I have this code
app.get('/imgs/:id', function(req, res) {
// Validate that req.params.id is 16 bytes hex string
// Get the stored image type for this image
var stream = fs.createReadStream(path.join(UPLOAD_PATH, req.params.id));
stream.on("readable", function() {
res.setHeader('Content-Type', "image/jpeg")
stream.pipe(res)
})
stream.on('error', (e) => {
res.redirect(404, "404")
})
});
Now the problem is that I always get an error of
Error: Can't set headers after they are sent.
because I used the res.setHeader function.
However, i don't know how to solve it. Let's say I want to use in a page, that has obviously the res.send() function has well,
the <img src="imgs/pic">, then I must set the header for the this page request to "image/jpeg" because otherwise the browser wouldn't know it's an image and won't show it as one.
What can I do then?
Check Express response document here. Try this code
app.get('/imgs/:id', function (req, res) {
res.sendFile(req.params.id, {root: UPLOAD_PATH, headers: {'Content-Type': 'image/jpeg'}}, function (err) {
if(err) throw err;
else console.log('sent')
})
})

Resources