首页 > 解决方案 > req.file 在多张图片上传中未定义——NodeJS、Angular

问题描述

我正在尝试使用 Multer 为博客文章上传图片。我在后端使用 mongodb 和 NodeJS,在前端使用 Angular。每当我执行 POST 请求并在控制台中检查时,req.file 总是 undefined。我曾尝试将 Multerupload.any()req.filesreq.files[0].filename无济于事。我不知道为什么它保持未定义。这是我的 Multer 代码:

const storage = multer.diskStorage({
    destination: (req, file, cb) => {
      cb(null, 'public');
    },
    filename: (req, file, cb) => {
      console.log(file);
      var filetype = '';
      if(file.mimetype === 'image/gif') {
        filetype = 'gif';
      }
      if(file.mimetype === 'image/png') {
        filetype = 'png';
      }
      if(file.mimetype === 'image/jpeg') {
        filetype = 'jpg';
      }
      cb(null, 'file-' + Date.now() + '.' + filetype);
    }
});

const upload = multer({storage: storage, limits: { fieldSize: 10 * 1024 * 1024 } });

这是服务器 POST 请求:

router.post('/newPost', passport.authenticate('jwt', { session: false}), upload.single('image'), function(req, res, next) {
  console.log(req.file); 
  let newPost = new Post({
    postTitle: req.body.postTitle,
    postAuthor: req.body.postAuthor,
    postImgUrl: 'http://localhost:3000/public/' + req.file.filename,
    postContent: req.body.postContent
  });

  Post.create(newPost, (err, user) => {
    if(err) {
      res.json({success: false, msg: 'Post failed to submit'});
    } else {
      res.json({success: true, msg: 'Successfully Posted'});
    }
  });
});

这是我的 POST 请求的 Angular 服务:

addPost(post): Observable<post> {
    this.loadToken();
    const head = this.headers.append("Authorization", this.authToken);
    return this.http.post<post>(this.baseUri + "/newPost", post, { headers: head });
  }

这是我的 TypeScript 组件代码:

export class BlogAddComponent implements OnInit {

    postTitle: '';
    postAuthor: '';
    postContent: '';
    postImgUrl: string;
    post: any[] = [];
    postForm: FormGroup;
    public editor = Editor;
    config;

  constructor(private postService: PostService,
    private formBuilder: FormBuilder,
    private router: Router,
    private flashMessage: FlashMessagesService) {
  }

  onFileSelect(event: Event) {
    const file = (event.target as HTMLInputElement).files[0];
    this.postForm.patchValue({ image: file });
    const allowedMimeTypes = ["image/png", "image/jpeg", "image/jpg"];
    if (file && allowedMimeTypes.includes(file.type)) {
      const reader = new FileReader();
      reader.onload = () => {
        this.postImgUrl = reader.result as string;
      };
      reader.readAsDataURL(file);
    }
  }

  ngOnInit(): void {

    this.postForm = new FormGroup({
      postTitle: new FormControl(null),
      postAuthor: new FormControl(null),
      postContent: new FormControl(null),
      postImgUrl: new FormControl(null)
    });
}

 onBlogSubmit() {
    this.postService.addPost(this.postForm.value).subscribe(
        data => {     
            this.flashMessage.show('Blog Submitted Successfully', {cssClass: 'alert-success', timeout: 3000});
            this.router.navigate(['/blog-page']);
        },
        error => {
            this.flashMessage.show('Something Went Wrong', {cssClass: 'alert-danger', timeout: 3000});
        }
    );
  }
}

这是我的组件 HTML:

<body>
  <div [formGroup]="postForm" class="container" *ngIf="post">
        <h1 class="mb-4">New blog post</h1>

        <form [formGroup]="postForm" (ngsubmit)="onBlogSubmit()" enctype="multipart/form-data">
            <div class="form-group">

                <label for="postImgUrl">Image</label>
                <input (change)="onFileSelect($event)" type="file" class="form-control" name="image" required>
            </div>

            <div class="form-group">

                <label for="title">Title</label>
                <input formControlName="postTitle" type="text" class="form-control" placeholder="Title" name="postTitle" required>
            </div>

            <div class="form-group">

                <label for="author">Author</label>
                <input formControlName="postAuthor" type="text" class="form-control" placeholder="Author" name="postAuthor" required>
            </div>
            <br>
            <div class="form-group">
              <ckeditor formControlName="postContent" name="postContent" [editor]="editor" [config]="config"></ckeditor>
            </div>
            <br>
            <div class="form-group">
                <a routerLink="/blog-page" class="btn btn-warning">Cancel</a>
                <button type="submit" class="btn btn-primary" (click)="onBlogSubmit()">Save</button>
            </div>
        </form>
    </div>
  </body>

我真的坚持这一点。非常感谢任何帮助、指示或指导。非常感谢您。

标签: node.jsangulartypescriptexpressmulter

解决方案


您应该使用您在后端配置formData的名称发送:image

addPost(post): Observable<post> {
    this.loadToken();
    const head = this.headers.append("Authorization", this.authToken);
    const formData: FormData = new FormData();
    formData.append('image', post.postImgUrl);
    return this.http.post<post>(this.baseUri + "/newPost", formData, { headers: head });
}

推荐阅读