【问题标题】:angular get image data and again append it to FormData角度获取图像数据并再次将其附加到 FormData
【发布时间】:2018-03-24 23:26:17
【问题描述】:

在 Angular 5 中,我通过我的服务从 mongodb 获取 hotelgallery 的图像。所以基本上我得到的数据是这样的

{
  fieldname: "hotelgallery", 
  originalname: "e.jpg", 
  encoding: "7bit", 
  mimetype: "image/jpeg", 
  destination: "./public/",
  encoding : "7bit",
  filename : "1521139307413.jpg"
  mimetype : "image/jpeg"
  path : "public/1521139307413.jpg"
  size : 66474
}
{
  fieldname: "hotelgallery", 
  originalname: "e.jpg", 
  encoding: "7bit", 
  mimetype: "image/jpeg", 
  destination: "./public/",
  encoding : "7bit",
  filename : "1521139307413.jpg"
  mimetype : "image/jpeg"
  path : "public/1521139307413.jpg"
  size : 66474
}
{
  fieldname: "hotelgallery", 
  originalname: "j.jpg", 
  encoding: "7bit", 
  mimetype: "image/jpeg", 
  destination: "./public/",
  encoding : "7bit",
  filename : "1526753678390.jpg"
  mimetype : "image/jpeg"
  path : "public/1526753678390.jpg"
  size : 66470
}
{
  fieldname: "hotelgallery", 
  originalname: "k.jpg", 
  encoding: "7bit", 
  mimetype: "image/jpeg", 
  destination: "./public/",
  encoding : "7bit",
  filename : "7865456789413.jpg"
  mimetype : "image/jpeg"
  path : "public/7865456789413.jpg"
  size : 66300
}

现在我想再次将这些数据附加到 FormData 但它不起作用。

到目前为止我所做的代码

export class HotelEditComponent implements OnInit {
   formData = new FormData();
   ngOnInit() {
    this.getOneHotel(this.route.snapshot.params['id']);
   }

 getOneHotel(id) {
    this.http.get( this.apiUrl + '/api/hotel/' + id).subscribe(data => {
      this.hotel = data;
      this.appendImages(data['hotelimages']); //Here I am getting the data as mentioned here
    });
 }

 public appendImages(imagedata) {
    for (var i = 0; i < imagedata.length; i++) {
      console.log(imagedata[i]);
      this.formData.append('hotelgallery', imagedata[i], imagedata[i]['originalname']);
    }
    console.log(this.formData);
  }
 }

那么有人可以告诉我如何将现有的图像数据附加到 FormData 中吗?任何帮助和建议都会非常重要。

用例: 实际上我曾使用 formData 以角度上传图像。现在在编辑页面中,图像显示正常。但是假设用户编辑了一些数据并上传了一些图像或删除了一些图像。在这种情况下,我从数据库中获取图像并再次尝试使用 formdata 上传它们。

我已经使用this 模块和 multer 为 nodejs 上传带有 formData 的图像。

【问题讨论】:

  • data['hotelimages'] 应该做什么?您从服务获得的数据中没有 hotelimages 属性。 imagedata[i] 包含什么?
  • 显示图片应该是data['path']
  • 实际上数据是一个对象,我从 data['hotelimages'] 获取所有图像的数据。
  • 乍一看,我认为您使用了错误的 FormData.append() 重载。具有 3 个参数的那个是用于第二个参数是 Blob/File 的情况,而你的参数似乎不是。参考:developer.mozilla.org/en-US/docs/Web/API/FormData/append
  • 我不明白你实际上想做什么(用例)。也许你可以再描述一下。

标签: javascript angular form-data


【解决方案1】:

那么有人可以告诉我如何将现有的图像数据附加到 FormData 中吗?任何帮助和建议都会非常重要。

实际上,这种方法需要更多的添加脚本解决方案。例如

1.从服务器获取图像 Blob

由于您返回图像的详细对象,而不是 blob。您需要有一个端点以作为 blob 返回。 (或者如果作为数据缓冲区返回,那么它会转换为 blob,您可以使用 BlobUtil

2。将 Blob 用于追加表单数据

您需要使用 blob 在参数 2 中追加无路径,请参阅 documentation

姓名

其数据包含在 value 中的字段的名称。

价值

字段的值。这可以是 USVString 或 Blob(包括子类 例如文件)。

文件名可选

报告给服务器的文件名 (USVString),当 Blob 或 File 作为第二个参数传递时。 Blob 对象的默认文件名是“blob”。默认文件名 对于 File 对象是文件的文件名。

这是你需要的,但这是不好的做法

假设您有 30 个图像要编辑,那么您需要请求 blob 端点来获取这些图像 blob 以追加。但是用户只想更新 1 个图像,浪费时间请求图像 blob,对吧?

对于edit图像,我们通常不需要追加到文件形式(&lt;input type="file" /&gt;)。

只需将其显示为缩略图即可查看上传的图像并让文件形式为空。

我们通常做的,就是缩略图。

当用户改变什么时,用户放置新图像并用新的想要替换旧图像并更新数据库。

如果不是,则不为图像执行任何操作。 (YAGNI)

【讨论】:

    【解决方案2】:

    FormData 的追加在这里静默失败。您需要将“图像”附加为 blob。请参阅MDN docs

    formData.append('hotelgallery', new Blob([imagedata[i]], { type: "text/xml"}), imagedata[i]['originalname']);
    

    另外,仅打印 formData 不会显示任何内容,而是尝试:

    console.log(this.formData.getAll('hotelgallery'));
    

    for (var value of this.formData.values()) {
       console.log(value);
    }
    

    【讨论】:

      【解决方案3】:

      但是假设用户编辑了一些数据并上传了一些图片或删除 一些图像。在那种情况下,我从数据库中获取图像 并再次尝试使用 formdata 上传它们。

      因此,您可以将对象传递给通用方法,并在结果上获得formData。对象数据甚至可以包含嵌套对象。

       static createFormData(object: Object, form?: FormData, namespace?: string): FormData {
              const formData = form || new FormData();
              for (let property in object) {
      
                  if (!object.hasOwnProperty(property) || object[property] === undefined) {
                      continue;
                  }
      
                  const formKey = namespace ? `${namespace}[${property}]` : property;
      
                  if (object[property] instanceof Date) {                 
                      formData.append(formKey, object[property].toISOString());
                  } else if (typeof object[property] === 'object' && !(object[property] instanceof File)) {
                      this.createFormData(object[property], formData, formKey);
                  }
                  else if (typeof object[property] === 'number') {
                      let numberStr = object[property].toString().replace('.', ',');
                      formData.append(formKey, numberStr);
                  }
                  else {
                      formData.append(formKey, object[property]);
                  }
              }
      
              return formData;
          }
      }
      

      在组件类中:

      export class HotelEditComponent implements OnInit {
         formData = new FormData();
         hotel: any;
         ...
         ngOnInit() {
          this.getOneHotel(this.route.snapshot.params['id']);
         }
      
       getOneHotel(id) {
          this.http.get( this.apiUrl + '/api/hotel/' + id).subscribe(data => {
            this.hotel = data;
          });
       }
      
       postToServer() {
        // or even can pass full `this.hotel` object
        // this.helperService.createFormData(this.hotel) 
        this.formData = this.helperService.createFormData(this.hotel['hotelimages']) 
        this.service.post(this.formData);
      
       }
      ...
      }
      

      【讨论】:

        【解决方案4】:

        您似乎正在尝试附加 JSON 数组,因为 formData.append 只能接受字符串或 blob,请尝试使用 JSON.stringify() 方法将您的数组转换为 JSON 字符串。 (未经测试)

        例如我认为你可以替换

        this.appendImages(data['hotelimages']);
        

        this.formData.append('hotelgallery', JSON.stringify(data['hotelimages']));
        

        【讨论】:

          【解决方案5】:

          现在这更多是设计问题,而不是技术问题。您正在询问是否再次发布 FormData 并且您想为此再次获取图像数据。

          现在让我们看看您当前的设计。

          1. 用户上传 3 张图片,每张 4MB 大小
          2. 在您的编辑页面上,您下载这些图像中的每一个。费用=12MB
          3. 在编辑页面上,用户删除了 2 个图像并添加了 2 个图像。费用=12MB
          4. 因此,更新 2 张 8MB 图像的最终成本为 24MB。很多

          现在在弄清楚如何使用 FormData 之前,先为您的应用找出正确的设计。

          考虑一下OLX 网站,它允许您发布广告并稍后对其进行编辑。当您编辑和删除图像时,它们会调用用于删除图像的 API

          我认为理想的设计如下

          • 提交您创建的所有图片
          • 为编辑创建图像的添加和删除端点

          在编辑表单上再次提交文本数据是可以的,但在编辑表单上再次提交相同的图像数据是不行的。重新考虑你的设计

          【讨论】:

            猜你喜欢
            • 2019-05-13
            • 1970-01-01
            • 1970-01-01
            • 2017-01-18
            • 1970-01-01
            • 2020-10-19
            • 1970-01-01
            • 2021-12-06
            • 2015-05-31
            相关资源
            最近更新 更多