Reputation: 2467
I know there's two other similar questions, but mine just isn't working and I'm not sure why.
I'm trying to serve a blob image saved in base64 on a nodejs server.
It's just not serving and I have no clue why. If I comment out the "writeHead" part it shows the base64 like it should. I've tried it with data:image/jpeg
and without. I've also tried converting it to a buffer. Just can't seem to figure it out.
The base64 image is less than 200 kb and is saved in a mediumblob
Can anyone see what I'm doing wrong
app.get("/f/:id", async function(req, res) {
r = await Files.get(req);
if(r.err.code){
console.log("error",r);
}
var file = r.res.file;
res.writeHead(200, {
'Content-Type': 'image/png',
'Content-Length': file.length
});
res.end(file);
});
Here's what it looks like in the browser
Here's what it looks like without writeHead enabled
Note: the "viewPortSize" id element at the bottom is an extension.
Edit #1: Also on Firefox it says "the image cannot be displayed because of errors" This must mean I've encoded it into base64 incorrectly right?
Edit #3: Actually it is saved correctly because if I remove headers and display it as html with an img and src it shows the image properly..now I really don't know what the issue is.
Edit #2:Here's the app.js setup
// ==============================================
// Base setup
// ==============================================
process.env.TZ = "Etc/GMT"
const express = require('express');
const session = require('express-session');
const app = express();
const port = 3075;
const bodyParser = require('body-parser');
app.use(bodyParser.urlencoded({limit: '50mb', extended: true }));
app.use(bodyParser.json({limit: '50mb'}));
app.use(require('express-useragent').express());
app.use(session({
secret: 'keyboard cat',
resave: false,
saveUninitialized: true,
cookie: { secure: true }
}))
// Cors
app.use(async function(req, res, next) {
let allowOrigins = [
// removed for SO
];
if(Config.Env === Environments.Local){
res.header("Access-Control-Allow-Origin", "*");
req.session.language = req.query.lg;
}else{
res.header("Access-Control-Allow-Origin", Config.FrontEnd.Url);
var origin = req.get('origin');
for (let i = 0; i < allowOrigins.length; i++) {
const allowOrigin = allowOrigins[i];
if(origin.match(allowOrigin)){
res.header("Access-Control-Allow-Origin", origin);
}
}
var subdomain = origin.split('.')[0];
for (let j = 0; j < availableLanguages.length; j++) {
const lang = availableLanguages[j];
if(lang.code === subdomain){
req.session.language = lang.code;
break;
}
}
}
// if(Config.Env !== Environments.Local){
if(req.session.language !== undefined && req.session.language !== "en"){
Config.FrontEnd.Url = Config.FrontEnd.Url.replace("://", "://"+req.session.language+".");
}
// }
res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept, auth-id, auth-token, x-csrf-token, _csrf");
res.header('Access-Control-Allow-Methods', 'PATCH, POST, GET, DELETE, OPTIONS');
next();
});
Edit #4: If I send it like this(with the data part on it) , the image shows like it should. However the headers are not of an image. (if I change to image it goes back to the black screen)
app.get("/f/:id", async function(req, res) {
r = await Files.get(req);
if(r.err.code){
console.log("error",r);
}
var file = r.res.file;
res.end(
'<html>'+
'<head></head>'+
'<body>'+
'<img src="'+file+'">'+
'</body>'+
'</html>'
);
});
Upvotes: 1
Views: 5535
Reputation: 74889
If the database stores a data:image/png;base64,xxxx
string then it would need to be converted back to the binary data to be part of a response with a content type of image/png
(like a regular image file).
const img_base64 = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAAHElEQVQI12P4//8/w38GIAXDIBKE0DHxgljNBAAO9TXL0Y4OHwAAAABJRU5ErkJggg=='
const server = require('http').createServer((req,res)=>{
console.log('got req', req.url)
// Extract image data
const m = /^data:(.+?);base64,(.+)$/.exec(img_base64)
if (!m) throw new Error(`Not a base64 image [${img_base64}]`)
const [ _, content_type, file_base64 ] = m
const file = Buffer.from(file_base64,'base64')
res.writeHead(200, {
'Content-Type': content_type,
'Content-Length': file.length
});
res.end(file);
})
server.listen(3132, ()=> console.log('hi', server.address()))
Upvotes: 9