This is my frontend React code:
import * as React from 'react';
import { useEffect, useState } from 'react';
import http from './http-common'; // axios
type Photo = {
filename: string,
caption: string,
tags: string[].
};
const BrowserArticle = ({ filename, caption, tags }: Photo) => {
const [photoFile, setFile] = useState<string>('');
useEffect(() => {
http.get(`/api/getImg/${filename}`)
.then((response) => {
console.log(typeof response.data); // console output is 'string'
console.log(response); // see screenshot below
setFile(data);
});
}, []);
return (
<div>
<img src={photoFile} alt={filename} />
<div>{caption}</div>
<div>
{
tags.map((tag) => tag)
}
</div>
</div>
);
};
This is my backend FastAPI code:
from fastapi import FastAPI
from fastapi.responses import FileResponse
from fastapi.staticfiles import StaticFiles
app = FastAPI()
app.mount('/static', StaticFiles(directory='static'), name='static')
@app.get('/api/getImg/{image_filename}')
async def get_image(image_filename: str) -> FileResponse:
return FileResponse(f'./static/uploads/{image_filename}')
CORS has been taken care of. When I send a request to the server, a response was successfully received, but the image could not load. Upon inspection, this is the generated HTML:

When I console.log(data) inside the then() function, this is what I got:

When I tested the API using FastAPI's built-in tool, I verified that the API is successfully returning blob:http://192.168.1.201:8000/0a870a00-cf63-43ef-b952-e49770137fdd
My suspicion is that the data received by axios is the image file itself, so I tried changing my code as follows:
const [photoFile, setFile] = useState<File | null>(null);
// ...
<img src={photoFile === null ? '' : URL.createObjectURL(photoFile)} alt={filename} />
But when I refresh the page, I get TypeError: Failed to execute 'createObjectURL' on 'URL': Overload resolution failed.
I tried searching up how to correctly display an image received from the backend, but the only results I found discussed how to send images to the backend or how to display images being uploaded to server (i.e. display thumbnails of files selected for upload via <input type="file" />. Nothing with regards to this particular problem. Any ideas?
Update: When I did the following, the image is displayed successfully:
<img src={`http://192.168.1.201:8000/api/getImg/${filename}`} alt={filename} />
But that would mean exposing my backend within the generated HTML, and hardcoding the backend IP. Is there a more "proper" way of doing this?
The way I figured out how to do it was by encoding the image as base64 in FastAPI, sending the base64 encoded image to frontend with an API call and rendering the image in the base64 encoded format in React. Here is some of the code for it.
FastAPI code (Remember NOT to use response_model=FileResponse)
with open(imgpath, 'rb') as f:
base64image = base64.b64encode(f.read())
return base64image
React code.
<img src={data:image/jpeg;base64,${data}} />
Here, ${data} is the base64 encoded image.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With