【问题标题】:VueJs Axios Post FormData ParametersVueJs Axios Post FormData 参数
【发布时间】:2019-01-03 16:33:13
【问题描述】:

我们在前端应用程序中使用 Vue,对于我们的一项 REST 服务,我们的后端服务器(使用 spring 和 java)期望具有以下数据结构:

public class MAProductsUploadRequest
{
    public List<MAProductUploadRequest> products;
}

public class MAProductUploadRequest {

    public String productName;
    public String productDescription;
    public double productPrice;
    public int productOrder;
    public MultipartFile productImage=null;
    public double cropX;
    public double cropY;
    public double cropWidth;
    public double cropHeight;
    public int categoryId;
}

在我们的 Vuejs 应用程序中,我们尝试按照以下代码发布数据:

      addProducts: function () {
        console.log("Add Products Working. Total Product Count:"+this.excelProducts.length);
        let header = {
          headers: auth.getAuthHeader()
        };

        let formData = new FormData();

        for (let i=0;i<this.excelProducts.length;i++ ) {

           console.log("Starting loop:"+i);
           var prod = this.excelProducts[i];
           console.log("Product Before:"+prod);
           if (document.getElementById('photo-image-'+i) !== null) {
             if(document.getElementById('photo-image-'+i).files.length !== 0) {
               console.log("Getting Image For Prod");
               prod.productImage = document.getElementById('photo-image-'+i).files[0] ;
             }
           }

          prod.cropX = this.cropProp.x;
          prod.cropY = this.cropProp.y;
          prod.cropWidth = this.cropProp.width;
          prod.cropHeight = this.cropProp.height;
          prod.rotate = this.cropProp.rotate;


          console.log("Product After:"+prod);
          formData.append("products[]",prod);

        }

        for (var pair of formData.entries()) {
          console.log(pair[0]+ ', ' + pair[1]);
        }

        //console.log("Form Data:"+formData.products);

        if (formData.products !== null) {
          axios.post(`${API_URL}/company/uploadProducts`, formData, header).then((response) => {
            logForDevelopment(response);
            this.getProducts();
            this.product = {
              id: '',
              name: '',
              description: '',
              price: '',
              photo: '',
              isEdit: false
            };
            this.excelProducts = [];
            this.isPhotoChosen = false;
            this.isPhotosChosen = [];
            this.cropImg = '';
            document.getElementById('photo-image').value = null;
            this.isLoading = false;
          }).catch((error) => {
            this.isLoading = false;
            if(error.response) {
              logForDevelopment(error);
              document.getElementById('photo-image').value = null;
              if(error.response.status === 401 || error.response.status === 403) {
                auth.afterInvalidToken('login');
              }
            }
          })
        }  else {
          console.log("Form Data Is Empty");
        }



      },

但是当我们使用此代码时(即使照片图像为空),后端服务器也会返回 HTTP 500 错误。因为 products 数组似乎为空。 我无法弄清楚问题可能出在 Vuejs 代码中?

编辑:(我也试过下面的代码,但结果还是一样)

      addProducts: function () {
        console.log("Add Products Working. Total Product Count:"+this.excelProducts.length);
        let header = {
          headers: auth.getAuthHeader()
        };

        let formData = new FormData();
        let prods = [];

        for (let i=0;i<this.excelProducts.length;i++ ) {

           console.log("Starting loop:"+i);
           let prod = this.excelProducts[i];


           let subFormData = new FormData();
           subFormData.append("productName",prod.productName);
           subFormData.append("productDescription",prod.productDescription);
           subFormData.append("productPrice",prod.price);
           subFormData.append("categoryId",prod.categoryId);
           subFormData.append("cropX",this.cropProp.x);
           subFormData.append("cropY",this.cropProp.y);
           subFormData.append("cropWidth",this.cropProp.width);
           subFormData.append("cropHeight",this.cropProp.height);

           prods.push(subFormData);



           if (document.getElementById('photo-image-'+i) !== null) {
             if(document.getElementById('photo-image-'+i).files.length !== 0) {
               console.log("Getting Image For Prod");
               subFormData.productImage = document.getElementById('photo-image-'+i).files[0] ;
             }
           }


        }

        formData.append("products",prods);

        console.log("Form Data:"+formData);

        if (formData.products !== null) {
          axios.post(`${API_URL}/company/uploadProducts`, formData, header).then((response) => {
            logForDevelopment(response);
            this.getProducts();
            this.product = {
              id: '',
              name: '',
              description: '',
              price: '',
              photo: '',
              isEdit: false
            };
            this.excelProducts = [];
            this.isPhotoChosen = false;
            this.isPhotosChosen = [];
            this.cropImg = '';
            document.getElementById('photo-image').value = null;
            this.isLoading = false;
          }).catch((error) => {
            this.isLoading = false;
            if(error.response) {
              logForDevelopment(error);
              //document.getElementById('photo-image').value = null;
              if(error.response.status === 401 || error.response.status === 403) {
                auth.afterInvalidToken('login');
              }
            }
          })
        }  else {
          console.log("Form Data Is Empty");
        }



      },

我实际上想要实现的是,我们的以下代码在将单个产品信息发送到我们的后端服务时工作正常,但我想将其设为一个数组,以便一次发送多个产品:

      addProduct: function () {

        let header = {
          headers: auth.getAuthHeader()
        };

        let formData = new FormData();

        formData.append('productName', this.product.name);
        formData.append('productDescription', this.product.description === '' ? "" : this.product.description);
        formData.append('productPrice', this.product.price);
        formData.append('categoryId', this.product.categoryId);
        if(document.getElementById('photo-image').files.length !== 0) {
          formData.append('productImage', document.getElementById('photo-image').files[0]);
        }
        formData.append('cropX', this.cropProp.x);
        formData.append('cropY', this.cropProp.y);
        formData.append('cropWidth', this.cropProp.width);
        formData.append('cropHeight', this.cropProp.height);
        formData.append('rotate', this.cropProp.rotate);

        console.log(formData);

        axios.post(`${API_URL}/company/products`, formData, header).then((response) => {
          logForDevelopment(response);
          this.getProducts();
          this.product = {
            id: '',
            name: '',
            description: '',
            price: '',
            photo: '',
            isEdit: false
          };
          this.isPhotoChosen = false;
          this.cropImg = '';
          document.getElementById('photo-image').value = null;
          this.isLoading = false;
        }).catch((error) => {
          this.isLoading = false;
          if(error.response) {
            logForDevelopment(error);
            document.getElementById('photo-image').value = null;
            if(error.response.status === 401 || error.response.status === 403) {
              auth.afterInvalidToken('login');
            }
          }
        })

      },

有人知道吗?

您也可以在下面查看我的应用程序的屏幕截图(我想一次发送屏幕截图中的所有项目)

【问题讨论】:

  • 你不是按 F12 打开 DevTools 看看 XHR 到底发送了什么吗?

标签: json spring vue.js axios


【解决方案1】:

您的问题可能出在 FormData 类的 formData.append("products[]",prod) 方法上,请尝试将 formData.append("products[]",prod) 更改为 formData.products.push(prod)

此外,如果您的 API 端点需要产品,那么在您的 axios 调用中,有效负载应该是 formData.products 吗? 试试axios.post(${API_URL}/company/uploadProducts, formData.products, header)

我没有看到任何与 Vue 相关的语法问题,希望这会有所帮助。 (当然还要按照 cmets 中的建议检查 XHR 在 devtools 中发送的内容)

【讨论】:

  • 我已经编辑了我的第一篇文章,并根据您的建议附上了我尝试过的代码,但后端的结果仍然相同
  • 您在 axios 后调用中仍然只传递 formData 作为有效负载数据,这是故意的吗?您不应该将formData.products 发送到您的后端吗?
  • 是的,因为在我们的 spring 后端服务中,它需要一个名为 products 的数组(您可以在第一个主题的顶部看到我们的后端结构),我猜实际的问题是,我无法创建模型正确地在 vuejs 客户端
  • 我还编辑了我的代码并在其中添加了一些粗线,因此您可以在这里看到我真正想要实现的目标
  • 抱歉,但据我了解,此调用 axios.post(${API_URL}/company/uploadProducts, formData, header) 发送一个对象 (formData)。所以,如果你想按你说的发送数组,你应该发送axios.post(${API_URL}/company/uploadProducts, formData.products, header), --> formData.products 就是你说的数组关于。那么当然你的后端必须能够处理一个数组而不是一个对象(JSON),否则它会“崩溃”。
猜你喜欢
  • 2019-02-28
  • 2021-10-13
  • 2019-07-08
  • 1970-01-01
  • 1970-01-01
  • 2018-02-15
  • 2018-06-08
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多