изображение 404 (не найдено) после загрузки, но работает при повторной компиляции веб-пакета

avatar
Sushil
8 апреля 2018 в 06:43
546
1
0

Я создаю приложение MEAN STACK CRUD (с Angular CLI). Проблема: когда я загружаю изображение, оно не отображается на странице с ОШИБКОЙ: GET http://localhost:4200/assets/images/uploadedProfilePic5ac9ade58bd8213eecf2aa50.jpg 404 (Not Found). Но он сразу появляется при повторной компиляции веб-пакета angular. нет никаких проблем с процессом загрузки изображения. он работает нормально. изображения загружаются туда, куда они должны быть загружены (src/assets/images), с этим также нет проблем. что мне теперь делать?.

Мой сервис для загрузки фото:

//upload Picture service
  uploadProfilePic(id, file)
  {
    const req = new HttpRequest(
      'POST', 
      'http://localhost:3000/users/uploadPic/'+id, file, {
      reportProgress: true
    });

    return this.http.request(req).map(res => {return res});
  }

Мой файл upload-profile-pic.component.ts:

onUpload(e)  
  {
    // console.log(e);

    const uploadData = new FormData();
    uploadData.append("uploadedProfilePic", this.file);

    this.auth.uploadProfilePic(this.id, uploadData).subscribe((data:any) => {

      if(data.type == 1){
        // console.log(Math.round(data.loaded*100/data.total));
        this.progressBarValue = Math.round(data.loaded*100/data.total);
      }

    setTimeout(()=>{ 
      if(data.type == 4){
        // console.log(data);
      var updateData = {avatar: "uploadedProfilePic"+this.id+'.'+this.ext};

      if(data.body.success) {
        this.auth.updateUserService(this.id, updateData).subscribe((data:any)=> {
          // console.log(data);
          if(data.success){
            this.flashMsg.show("Success: "+ data.msg, {cssClass: 'flashMessageBox', timeout: 6000});
            this.router.navigate(['/userList']);
          }else{
            this.flashMsg.show("Error: "+ data.msg, {cssClass: 'flashMessageBox', timeout: 6000});
            // this.reset();
            this.router.navigate(['/userList']);
          }
        });

      }else {
        this.flashMsg.show("Error: "+ data.body.msg, {cssClass: 'flashMessageBox', timeout: 6000});
        // this.reset();
        this.router.navigate(['/userList']);
        }
      }
    }, 2000);

    });


  }

Мой html-файл со списком пользователей, где показано изображение:

<div *ngFor = "let user of usersList">
    <div class="row mb-2 mx-auto" id="showUserList">

      <div class="col-sm-2 p-0 text-center">

        <img *ngIf="!user.avatar == ''" src="{{photoBaseUrl}}/{{user.avatar}}" class="img-thumbnail" alt="user image" id="profilePic1">
        <img *ngIf="user.avatar == ''" src="{{photoBaseUrl}}/usergroup.png" class="img-thumbnail" alt="user image" id="profilePic2">
        <div class="overlay">
          <p class="addPicText" routerLink="/uploadProfilePic/{{user._id}}">
            <i class="far fa-user addPhIcon"></i>
            <br> 
            Update
          </p>
        </div>
      </div>

      <div class="col-sm-7">
        <div class="card-body py-0">
          <h5 class="card-title text-capitalize my-0 pt-1">{{user.name}}</h5>
          <p class="card-text text-muted p-0 m-0 font-sm">Email : {{user.email}}</p>
          <p class="card-text text-muted p-0 m-0 font-sm">Phone : {{user.phone}}</p>
          <p class="card-text text-muted p-0 m-0 text-capitalize font-sm">Active : {{user.active}}</p>         
        </div>
      </div>

      <div class="col-sm-3 pr-0 mr-0">
        <div class="w-75 mx-auto mt-2 text-uppercase">
          <p 
            routerLink="/editUser/{{user._id}}" 
            class="btn btn-outline-primary btn-block btnStyleSuccess font-xs m-0 p-1 mb-1">
            <i class="far fa-edit"></i> 
            Update
          </p>
          <p 
            (click)="openConfDialog(user._id)" 
            class="btn btn-outline-primary btn-block btnStyleDanger font-xs m-0 p-1">
            <i class="far fa-trash-alt"></i> 
            Delete
          </p>
        </div>        
      </div>
    </div>
  </div> 

в файле userlist.component.ts,

ngOnInit() {
    this.getUsers();
    this.photoBaseUrl = '../../assets/images';    
  }

В Back-end Мое изображение загрузить файл контроллеров :

controller.storage = multer.diskStorage({
    destination: './angular-crud/src/assets/images',
    filename: function(req, file, cb){
      cb(null, file.fieldname + req.params.id + path.extname(file.originalname));
    }
  });

маршрут загрузки внутреннего изображения: //загрузить профиль или аватар route

router.post('/uploadPic/:id', (req, res, next) => {
    controllers.upload(req, res, (err) => {
      if(err){
        res.json({
            success: false,
            msg: err
        });
        console.log(err);
      } else {
        if(req.file == undefined){
            res.json({
                success: false,
                msg: "Sorry! No File Selected."
            });
        }else{
          res.json({
            success: true,
            msg: "Great job! Image uploaded successfully."
          });
        }
      }
    });
  });
Источник

Ответы (1)

avatar
funkizer
8 апреля 2018 в 07:44
0

Похоже, вы используете ng serve, на котором работает Webpack Dev Server. Это создает приложение и обслуживает его из виртуального каталога. Он не обслуживает фактический src/assets, поэтому, если вы скопируете файл в src во время работы, он не обновит виртуальный каталог, пока вы не перестроите приложение.

.

Поскольку вам нужна функция загрузки, пришло время вместо этого реализовать обслуживание статических файлов на вашем сервере Express:

const path = require('path');
app.use(express.static(path.join(
    __dirname, '..', 'path', 'to', 'client-app', 'dist'
)));

Затем вместо ng serve запустите ng build --dev --watch, чтобы он перестроился в dist при изменении кода Angular.

Изменить: Обратите внимание, что вы не должны использовать dist для загруженных файлов, если вы заботитесь о сохранении этих файлов. Каждый раз, когда ng cli перестраивает приложение, dist будет стираться. Поэтому вместо этого используйте другой каталог загрузки, который находится за пределами папки dist, созданной ng cli. Вы также можете указать Express обслуживать файлы оттуда, используя другой вызов express.static. Assets-directory следует использовать только для статических ресурсов, которые принадлежат вашему приложению и поставляются вместе с ним.

Sushil
9 апреля 2018 в 03:59
0

когда я даю команду, процесс начался, но не завершил создание пакета. пробовал 3, 4 раза.

Sushil
9 апреля 2018 в 05:19
0

нет. Это не. просто остановился и курсор моргнул.

funkizer
9 апреля 2018 в 05:43
0

Вы уверены, что он не строился и теперь ждет изменений? Есть ли каталог dist в этот момент?

Sushil
11 апреля 2018 в 06:10
0

Нет. Он не был построен полностью.

funkizer
11 апреля 2018 в 16:57
0

Обновите все в вашем package.json и глобальном @angular/cli, попробуйте еще раз, если все еще не работает, это, вероятно, тема для другого вопроса.