【问题标题】:req.file is undefined in multer image upload -- NodeJS, Angularreq.file 在多张图片上传中未定义——NodeJS、Angular
【发布时间】:2021-10-30 01:23:28
【问题描述】:

我正在尝试使用 Multer 为博客文章上传图片。我在后端使用 mongodb 和 NodeJS,在前端使用 Angular。每当我执行 POST 请求并在控制台中检查时,req.file 始终未定义。我曾尝试将 Multer 的 upload.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.js angular typescript express multer


    【解决方案1】:

    您应该发送 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 });
    }
    

    【讨论】:

    • 非常感谢您的回答。它解决了错误,但现在出现了一个新错误:SyntaxError: Unexpected token - in JSON at position 0。为什么会发生此错误,我该如何解决?
    • 它在哪里抛出错误?图片上传了吗?
    • 它在 nodejs 控制台中抛出错误。并且图片没有上传。
    • 您可以尝试仅发送带有image 参数的formData 并检查图像是否会上传?我更新了我的答案。
    • 我尝试只上传所要求的图片,但它给出了同样的错误:Unexpected token - in JSON at position 0
    猜你喜欢
    • 1970-01-01
    • 2019-06-27
    • 1970-01-01
    • 2022-01-18
    • 2017-07-23
    • 2019-04-04
    • 1970-01-01
    • 2020-12-17
    • 1970-01-01
    相关资源
    最近更新 更多