Reputation: 36205
I am working on a new project and learning ReactJS. I have saved an image in base64 to a MySQL database and I am now trying to do a GET request so the image is shown in the browser instead of it being downloaded, however, although it attempts to download the file, the file is just a file containing the base64 string instead of an actual image.
The file in the database looks like the below (only a snippet of the base64)
data:image/png;base64,iVBORw0KGgoAAAA
The API to fetch the image is as below:
export default async function handler(req : NextApiRequest, res : NextApiResponse) {
const prisma = new PrismaClient()
if (req.method === "GET")
{
const {image_id} = req.query;
const image = await prisma.images.findFirst({
where: {
imageId: parseInt(image_id)
}
});
const decoded = Buffer.from(image.content).toString("base64");
console.log(decoded)
res.status(200).send(decoded);
}
else
{
res.status(405).json(returnAPIErrorObject(405, "Method not supported by API endpoint"));
}
}
I've modified the next.config.js to provide a custom header response which contains the below:
module.exports = {
async headers() {
return [
{
source: '/api/images/:image_id',
headers: [
{
key: 'Content-Type',
value: 'image/png:Base64'
}
]
}
]
}
}
As mentioned, when I go to the URL http://localhost:3000/api/images/4
(4 being the image id) it downloads a file that contains the base64 string that is in the database, instead of showing the image in the browser.
UPDATE
Based on the link in the comment from @sean w it now attempts to display the image but instead of showing the actual picture, it just shows a blank window with a white square as shown in the screenshot below.
My code now looks like the following:
const {image_id} = req.query;
const image = await prisma.images.findFirst({
where: {
imageId: parseInt(image_id)
}
});
const decoded = Buffer.from(image.content, 'base64').toString();
let imageContent = decoded.replace(/^data:image\/png;base64,/, '');
console.log(decoded);
res.writeHead(200, {
'Content-Type': 'image/png',
'Content-Length': imageContent.length
});
res.end(imageContent);
Below is a screenshot showing what actually gets rendered on the page instead of my actual image.
Upvotes: 4
Views: 10512
Reputation: 36205
I've figured out the issue, instead of creating the buffer from the database which I think looks like Prisma as the column was a blob was giving me a buffer anyway. , I first extract the base64 string from the DB and remove the data:image/png;base64 from the string and then create a buffer from that string and send that for the response:
const {image_id} = req.query;
const image = await prisma.images.findFirst({
where: {
imageId: parseInt(image_id)
}
});
const decoded = image.content.toString().replace("data:image/png;base64,", "");
const imageResp = new Buffer(decoded, "base64");
res.writeHead(200, {
'Content-Type': 'image/png',
'Content-Length': imageResp.length
});
res.end(imageResp);
Upvotes: 8