I am building a MEAN stack app where I am taking an input via a form where the user upload an Image and it is shown as a profile picture. When I run the test in local the upload / image is retrieved and gets served on the dashboard perfectly. But when I run the same on a Ubuntu server using Ngnix, the image does not get served and it creates an error.
main.js?attr=LdHP7JnhhbzofGQTBXcmTkKMZ1Pzr4WXYCGSBFYftPK-jLQmZAWm17m_AHXg1JHn:2923
GET http://134.23.345.765/api/users/uploads/school/668a8a781b0520a147957c64/profilePicture-1720355513994-766311342.jpg 404 (Not Found)
main-K6PVWXK7.js:770 Error fetching photo B1 {headers: t, status: 404, statusText: 'Not Found', url: 'http://134.23.345.765/api/users/uploads/school/668…957c64/profilePicture-1720355513994-766311342.jpg', ok: false, …} error : Blob {size: 564, type: 'text/html'} headers : t {normalizedNames: Map(6), lazyUpdate: null, headers: Map(6)} message : "Http failure response for http://134.23.345.765/api/users/uploads/school/668a8a781b0520a147957c64/profilePicture-1720355513994-766311342.jpg: 404 Not Found" name : "HttpErrorResponse" ok : false status : 404 statusText : "Not Found" url : "http://134.23.345.765/api/users/uploads/school/668a8a781b0520a147957
Controller Function
async function getUploadByFilename(req, res) {
try {
const { filename } = req.params;
const userId = req.user.userId; // Extracted from JWT by authenticate middleware
const role = req.user.role; // Extracted from JWT by authenticate middleware
// Construct the file path based on your project structure
const filePath = path.join(
__dirname,
"..",
"..",
"userUploads",
role,
userId.toString(),
filename
);
// Log the file path for debugging
console.log(
"Coming from userController - Constructed file path:",
filePath
);
if (fs.existsSync(filePath)) {
res.sendFile(filePath);
} else {
res.status(404).json({ message: "File not found" });
}
} catch (error) {
console.error("Error fetching file:", error);
res.status(500).json({ message: "Internal server error" });
}
}
Router
router.get(
"/uploads/:role/:userId/:filename",
authenticate,
getUploadByFilename
);
User Route in Index.js
app.use("/api/users", userRoutes);
Angular Service
getPhotoByFilename(
role: string,
userId: string,
filename: string,
token: string
): Observable<Blob> {
const headers = new HttpHeaders({
Authorization: `Bearer ${token}`,
});
return this.http.get(
`${this.apiUrl}/uploads/${role}/${userId}/${filename}`,
{
headers,
responseType: 'blob',
}
);
}
dashboard.component.ts
ngOnInit(): void {
const token = this.userAuthService.getToken();
const userId = this.userAuthService.getUserId();
if (token && userId) {
this.userService.fetchUserProfile(token).subscribe({
next: (userProfile: UserProfile) => {
this.userEmail = userProfile.email;
if (userProfile.profileInfo) {
this.userFirstName = userProfile.profileInfo.firstName;
this.userLastName = userProfile.profileInfo.lastName;
}
// Use the photoUrl directly from the userProfile
console.log(`Received photoUrl-updated-5: ${userProfile.photoUrl}`);
// Replace backslashes with forward slashes
const photoUrlPath = userProfile.photoUrl.replace(/\\/g, '/');
if (photoUrlPath) {
const filename = photoUrlPath.split('/').pop(); // Extract filename
const role = userProfile.role;
if (filename) {
this.userService
.getPhotoByFilename(role, userId, filename, token)
.subscribe({
next: (photoBlob: Blob) => {
const reader = new FileReader();
reader.onload = () => {
this.photoUrl = reader.result as string;
};
reader.readAsDataURL(photoBlob);
},
error: (error: any) => {
console.error('Error fetching photo', error);
},
});
} else {
console.error('Filename extraction failed.');
}
} else {
console.error('Photo URL is missing.');
}
},
error: (error: any) => {
console.error('Error fetching user profile', error);
},
});
} else {
console.error('No token or userId found. Unable to fetch user profile.');
}
this.schoolNewProjectService.getAllUserProjects().subscribe({
next: (projects: SchoolNewProject[]) => {
this.projects = projects;
},
error: (error: any) => {
console.error('Error fetching projects:', error);
},
});
}
component.html
<div class="personal-info">
<img
[src]="photoUrl"
alt="Profile Photo"
style="border-radius: 50%; width: 100px; height: 100px"
/>
server config
server {
listen 80;
server_name 134.23.345.765;
root /var/www/dev.example.com/public_html/example/browser;
index index.csr.html index.html index.htm;
location / {
try_files $uri $uri/ @node_server;
}
location @node_server {
proxy_pass http://localhost:2300;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_set_header Host $host;
proxy_cache_bypass $http_upgrade;
}
location /api/ {
proxy_pass http://localhost:2300/api/;
proxy_http_version 1.1;
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_cache_bypass $http_upgrade;
}
location ~* \.(js|css|png|jpg|jpeg|gif|ico|svg|woff|woff2|ttf|eot)$ {
expires max;
log_not_found off;
}
location /api/users/uploads/ {
proxy_pass http://localhost:2300/api/users/uploads/;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
error_page 404 /404.html;
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root /usr/share/nginx/html;
}
location = /404.html {
root /usr/share/nginx/html;
}
}
index.js
?index.js
in the "index" list in your config file. I'm not an Nginx expert, but I don't see what would make it look forindex.js
here.