0

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;
    }
}
4
  • Your IP address is impossible. Can't have 765 in there. Have you shrouded it? Where have you told Nginx to run index.js? Commented Jul 8 at 3:52
  • Hello Tim, i have added a dummy IP here ..but the original ip is different. I am using proxy to run the index.js location @node_server { proxy code here } location /api/ { proxy code here } location /api/users/uploads/ { alias /var/www/backend/userUploads/; autoindex on; } Hope this clarifies, please help in this regard. Commented Jul 8 at 6:09
  • My point is that you don't have 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 for index.js here. Commented Jul 8 at 7:20
  • Thanks Tim. I got the resolution of this , I isolated the location of the uploads on the server by creating a simple config "test" site and then tested , it worked and with permissions. Commented Jul 8 at 9:22

0