axios POST请求击中控制器上的url,但将空值设置为我的POJO类,当我在chrome中通过开发人员工具时,有效载荷包含数据。我做错了什么?

Axios POST请求

var body = {
    userName: 'Fred',
    userEmail: 'Flintstone@gmail.com'
}

axios({
    method: 'post',
    url: '/addUser',
    data: body
})
.then(function (response) {
    console.log(response);
})
.catch(function (error) {
    console.log(error);
});

浏览器响应:

如果我设置头信息为:

headers:{
  Content-Type:'multipart/form-data'
}

请求抛出错误

在发布多部分/表单数据时出错。内容类型报头缺少边界

如果我在邮递员中提出相同的请求,它就会正常工作,并为我的POJO类设置值。

有人能解释如何设置边界或如何使用axios发送表单数据吗?


当前回答

在我的例子中,问题是FormData追加操作的格式需要额外的“options”参数填充来定义文件名:

var formData = new FormData();
formData.append(fieldName, fileBuffer, {filename: originalName});

我看到很多人抱怨axios有问题,但实际上根本原因是没有正确使用form-data。我的版本是:

"axios": "^0.21.1",
"form-data": "^3.0.0",

在接收端,我用multer处理这个,最初的问题是文件数组没有被填充-我总是得到一个没有从流解析文件的请求。

此外,有必要在axios请求中传递表单数据头集:

        const response = await axios.post(getBackendURL() + '/api/Documents/' + userId + '/createDocument', formData, {
        headers: formData.getHeaders()
    });

整个函数是这样的:

async function uploadDocumentTransaction(userId, fileBuffer, fieldName, originalName) {
    var formData = new FormData();
    formData.append(fieldName, fileBuffer, {filename: originalName});

    try {
        const response = await axios.post(
            getBackendURL() + '/api/Documents/' + userId + '/createDocument',
            formData,
            {
                headers: formData.getHeaders()
            }
        );

        return response;
    } catch (err) {
        // error handling
    }
}

“fieldName”的值并不重要,除非您有一些接收端处理需要它。

其他回答

你可以通过使用FormData()来发布axios数据,比如:

var bodyFormData = new FormData();

然后将字段添加到您想要发送的表单:

bodyFormData.append('userName', 'Fred');

如果你正在上传图片,你可能想要使用.append

bodyFormData.append('image', imageFile); 

然后你可以使用axios post方法(你可以相应地修改它)

axios({
  method: "post",
  url: "myurl",
  data: bodyFormData,
  headers: { "Content-Type": "multipart/form-data" },
})
  .then(function (response) {
    //handle success
    console.log(response);
  })
  .catch(function (response) {
    //handle error
    console.log(response);
  });

相关GitHub问题:

不能得到一个。post与'Content-Type': 'multipart/form-data'工作@ axios/axios

在我的例子中,问题是FormData追加操作的格式需要额外的“options”参数填充来定义文件名:

var formData = new FormData();
formData.append(fieldName, fileBuffer, {filename: originalName});

我看到很多人抱怨axios有问题,但实际上根本原因是没有正确使用form-data。我的版本是:

"axios": "^0.21.1",
"form-data": "^3.0.0",

在接收端,我用multer处理这个,最初的问题是文件数组没有被填充-我总是得到一个没有从流解析文件的请求。

此外,有必要在axios请求中传递表单数据头集:

        const response = await axios.post(getBackendURL() + '/api/Documents/' + userId + '/createDocument', formData, {
        headers: formData.getHeaders()
    });

整个函数是这样的:

async function uploadDocumentTransaction(userId, fileBuffer, fieldName, originalName) {
    var formData = new FormData();
    formData.append(fieldName, fileBuffer, {filename: originalName});

    try {
        const response = await axios.post(
            getBackendURL() + '/api/Documents/' + userId + '/createDocument',
            formData,
            {
                headers: formData.getHeaders()
            }
        );

        return response;
    } catch (err) {
        // error handling
    }
}

“fieldName”的值并不重要,除非您有一些接收端处理需要它。

2020 ES6的做法

我在html中绑定了这样的数据:

数据:

form: {
   name: 'Joan Cap de porc',
   email: 'fake@email.com',
   phone: 2323,
   query: 'cap d\ou'
   file: null,
   legal: false
},

onSubmit:

async submitForm() {
  const formData = new FormData()
  Object.keys(this.form).forEach((key) => {
    formData.append(key, this.form[key])
  })

  try {
    await this.$axios.post('/ajax/contact/contact-us', formData)
    this.$emit('formSent')
  } catch (err) {
    this.errors.push('form_error')
  }
}

在发送请求时设置边界(服务器用来解析有效负载)。在发出请求之前无法获得边界。因此,更好的方法是从你的FormData中使用getBoundary()。

var formData = new FormData();
formData.append('userName', 'Fred');
formData.append('file0', fileZero);
formData.append('file1', fileOne);

axios({
  method: "post",
  url: "myurl",
  data: formData,
  headers: {
      'Content-Type':  `multipart/form-data; ${formData.getBoundary()}`,
})
  .then(function (response) {
    //handle success
    console.log(response);
  })
  .catch(function (response) {
    //handle error
    console.log(response);
  });

上面的方法对我来说很有效,但因为这是我经常需要的东西,所以我使用了一个基本的方法来制作平面物体。注意,我也在使用Vue而不是REACT

packageData: (data) => {
  const form = new FormData()
  for ( const key in data ) {
    form.append(key, data[key]);
  }
  return form
}

这对我有用,直到我遇到更复杂的数据结构与嵌套对象和文件,然后让以下

packageData: (obj, form, namespace) => {
  for(const property in obj) {
    // if form is passed in through recursion assign otherwise create new
    const formData = form || new FormData()
    let formKey

    if(obj.hasOwnProperty(property)) {
      if(namespace) {
        formKey = namespace + '[' + property + ']';
      } else {
        formKey = property;
      }

      // if the property is an object, but not a File, use recursion.
      if(typeof obj[property] === 'object' && !(obj[property] instanceof File)) {
        packageData(obj[property], formData, property);
      } else {
        // if it's a string or a File
      formData.append(formKey, obj[property]);
      }
    }
  }
  return formData;
}