简体   繁体   English

MEAN堆栈multer图像上传意外字段错误

[英]MEAN stack multer image upload unexpected field error

I'm trying to upload a file via multer into the server, and I continuously get Unexpected field error even though every file name field is the same.我正在尝试通过 multer 将文件上传到服务器,尽管每个文件名字段都相同,但我不断收到意外字段错误。 I don't know what could cause the problem.我不知道是什么导致了这个问题。 Maybe someone can help?也许有人可以帮忙?

The error message: Error massage错误信息:错误消息

So these are my relevant codes:所以这些是我的相关代码:

Creating the formGroup which gets the image from the html page.创建从 html 页面获取图像的 formGroup。

in upload-property.component.ts在上传属性.component.ts

this.imageForm = new FormGroup({
        description: new FormControl(null),
        image: new FormControl(null, {
          asyncValidators: [mimeType]
        })
      })

Here's the onImagePicked function with the onSaveProperty function in the components ts file.这是组件 ts 文件中的 onImagePicked 函数和 onSaveProperty 函数。

onImagePicked(event: Event) {
      const file = (event.target as HTMLInputElement).files[0];
      this.imageForm.patchValue({ image: file });
      console.log("picked");
      this.imageForm.get("image").updateValueAndValidity();
      const reader = new FileReader();
      reader.onload = () => {
        this.imagePreview = reader.result as string;
      };
      reader.readAsDataURL(file);
}
    
onSaveProperty() {
      if (this.typeForm.invalid || this.addressForm.invalid || this.datasForm.invalid || this.optionalForm.invalid || this.imageForm.invalid ) {
        console.log("invalid form");
      }
      console.log("Not invalid");
      this.isLoading = true;
      if (this.mode === "create") {
        console.log("entered here");
        this.propertyService.addProp(
          this.typeForm.value.type,
          this.addressForm.value.city,
          this.addressForm.value.city2,
          this.addressForm.value.address,
          this.datasForm.value.size,
          this.datasForm.value.price,
          this.datasForm.value.numberOfRooms,
          this.datasForm.value.condition,
          this.datasForm.value.year,
          this.datasForm.value.heatingType,
          this.optionalForm.value.level,
          this.optionalForm.value.parking,
          this.optionalForm.value.elevator,
          this.optionalForm.value.garden,
          this.optionalForm.value.attic,
          this.optionalForm.value.pet,
          this.optionalForm.value.smoke,
          this.optionalForm.value.furnitured,
          this.imageForm.value.image,
          this.imageForm.value.description
        );
        console.log("after addprop");
      } else {
        this.propertyService.updateProp(
          this.prop.id,
          this.typeForm.value.type,
          this.addressForm.value.city,
          this.addressForm.value.city2,
          this.addressForm.value.address,
          this.datasForm.value.size,
          this.datasForm.value.price,
          this.datasForm.value.numberOfRooms,
          this.datasForm.value.condition,
          this.datasForm.value.year,
          this.datasForm.value.heatingType,
          this.optionalForm.value.level,
          this.optionalForm.value.parking,
          this.optionalForm.value.elevator,
          this.optionalForm.value.garden,
          this.optionalForm.value.attic,
          this.optionalForm.value.pet,
          this.optionalForm.value.smoke,
          this.optionalForm.value.furnitured,
          this.imageForm.value.image,
          this.imageForm.value.description
        );
      }
      console.log("before reset");
      this.addressForm.reset();
      this.datasForm.reset();
      this.optionalForm.reset();
      this.imageForm.reset();
      this.typeForm.reset();
    }
  }

On the property.service.ts:在 property.service.ts 上:

addProp(type: string, city: string, city2: string, address: string,  size: number, price: number, condition: string, year: number,
    numberOfRooms: number, parking: string, furnitured: boolean, garden: boolean, attic: boolean, pet: boolean, smoke: boolean,
    heatingType: string, elevator: boolean, description: string, level: number, image: File
    ) {
      console.log("INADDPROP");
      const propData = new FormData();
      propData.append("city", city);
      propData.append("city2", city2);
      propData.append("address", address);
      propData.append("condition", condition);
      propData.append("price", price as unknown as string);
      propData.append("year", year as unknown as string);
      propData.append("numberOfRooms", numberOfRooms as unknown as string);
      propData.append("garden", garden as unknown as string);
      propData.append("attic", attic as unknown as string);
      propData.append("heatingType", heatingType);
      propData.append("size", size as unknown as string);
      propData.append("elevator", elevator as unknown as string);
      propData.append("level", level as unknown as Blob);
      propData.append("furnitured", furnitured as unknown as Blob);
      propData.append("pet", pet as unknown as Blob);
      propData.append("smoke", smoke as unknown as Blob);
      propData.append("parking", parking);
      propData.append("description", description);
      propData.set("image", image);
      propData.append("type", type);
    this.http
      .post(
        this.url,
        propData
      )
      .subscribe(responseData => {
        this.router.navigate(["/"]);
      });
  }

On the serverside code:在服务器端代码:

const storage = multer.diskStorage({
  destination: (req, file, cb) => {
    const isValid = MIME_TYPE_MAP[file.mimetype];
    let error = new Error("Invalid mime type");
    if (isValid) {
      error = null;
    }
    cb(error, "backend/images");
  },
  filename: (req, file, cb) => {
    const name = file.originalname
      .toLowerCase()
      .split(" ")
      .join("-");
    const ext = MIME_TYPE_MAP[file.mimetype];
    cb(null, name + "-" + Date.now() + "." + ext);
  }
});
const upload = multer({storage: storage});
router.post(
  "",
  checkAuth,
  upload.single('image'),
  (req,res,next) => {
    const url = req.protocol + "://" + req.get("host");
    const prop = new Property({
      city: req.body.city,
      city2: req.body.city2,
      address: req.body.address,
      type: req.body.type,
      size: req.body.size,
      condition: req.body.condition,
      price: req.body.price,
      year: req.body.year,
      parking: req.body.parking,
      numberOfRooms: req.body.numberOfRooms,
      furnitured: req.body.furnitured,
      elevator: req.body.elevator,
      level: req.body.level,
      garden: req.body.garden,
      attic: req.body.attic,
      pet: req.body.pet,
      smoke: req.body.smoke,
      heatingType : req.body.heatingType,
      creator: req.userData.userId
  //    image: url + "/images/" + req.file.filename
    });
    prop.save().then(updatedProperty => {
      console.log(updatedProperty);
      res.status(201).json({
        message: "Post added successfully",
        prop: {
          ...updatedProperty,
          id: updatedProperty._id
        }
      });
    });
  }
);

And that's it.就是这样。 I'm really desperate, I'm looking for a solution for days and so far I got nothing.我真的很绝望,我几天来一直在寻找解决方案,但到目前为止我一无所获。 I really appreciate any help.我真的很感激任何帮助。

Content-Type标头设置为multipart/form-data

Since your code looks ok ( upload.single('image') matches the name of the image in your form-data) it could be that checkAuth or other middlewares have already consumed the request payload.由于您的代码看起来没问题( upload.single('image')与表单数据中的图像名称匹配),可能是checkAuth或其他中间件已经消耗了请求负载。 If that's the case then there will be nothing left in the stream to consume for multer.如果是这种情况,那么流中将没有任何东西可供 multer 消费。

Try disabling checkAuth or preceding other middlewares to find the culprit.尝试禁用checkAuth或在其他中间件之前找到罪魁祸首。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM