axios post 请求发送表单数据

IT技术 reactjs react-redux axios ajaxform axios-cookiejar-support
2021-03-25 23:27:16

axiosPOST请求正在访问控制器上的 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 发送表单数据。

6个回答

您可以使用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 问题:

无法获得带有 'Content-Type': 'multipart/form-data' 的 .post 来工作@axios/axios

您需要使用 append 而不是 set。
2021-05-27 23:27:16
你的配置对象是错误的。它应该是:{ method: 'post', url: 'myurl', data: bodyFormData, headers: {'Content-Type': 'multipart/form-data' } }
2021-06-05 23:27:16
bodyFormData.set 不是一个函数,我收到了这个错误
2021-06-08 23:27:16
在 nodejs 中你需要 npm install --save form-data
2021-06-08 23:27:16
@ManojBhardwaj 您需要绑定该函数,假设您在提交函数中发出请求,您需要绑定该函数。ex:- onSubmit={this.submit(bind(this)} 或 ex:- 在构造函数构造函数(super){ this.submit = this.submit.bind(this); } submit(){ axios({}) ;... }
2021-06-20 23:27:16

在我的情况下,我必须将边界添加标题中,如下所示:

const form = new FormData();
form.append(item.name, fs.createReadStream(pathToFile));

const response = await axios({
    method: 'post',
    url: 'http://www.yourserver.com/upload',
    data: form,
    headers: {
        'Content-Type': `multipart/form-data; boundary=${form._boundary}`,
    },
});

如果您使用 React Native,此解决方案也很有用。

@KevinRED 是的,当时我实际上是在使用 React Native 和 iOS 应用程序...
2021-05-22 23:27:16
嗨,有一个问题,虽然这仅适用于 android,但您是否设法使其在 iOS 设备上运行?
2021-05-29 23:27:16
FormData._boundary在 Chrome 76 和 Firefox 67 中都未定义,并且axios 无论如何都会删除 Content-Type 标头,因此这应该无效。
2021-05-31 23:27:16
边界部分是我的代码中唯一缺少的部分,在节点中完美运行!
2021-06-02 23:27:16
这解决了我在尝试发布到 imgur 的 api 时的问题。文档中没有提到任何地方,但如果没有它,您会收到 400 Invalid URL 响应。
2021-06-19 23:27:16

查看查询字符串

您可以按如下方式使用它:

var querystring = require('querystring');
axios.post('http://something.com/', querystring.stringify({ foo: 'bar' }));
如果您的数据中有嵌套对象,“querystring”可能无法按预期工作。在这种情况下,您可以使用 'qs' module对数据进行字符串化。
2021-05-30 23:27:16
出于某种原因,不推荐使用查询字符串包
2021-06-04 23:27:16
这在节点环境中甚至更好
2021-06-06 23:27:16
这不是表单数据。这是一种 url 编码的表单格式。
2021-06-11 23:27:16

上传(多个)二进制文件

节点.js

当您想通过 发布文件时事情变得复杂multipart/form-data,尤其是多个二进制文件。下面是一个工作示例:

const FormData = require('form-data')
const fs = require('fs')
const path = require('path')

const formData = new FormData()
formData.append('files[]', JSON.stringify({ to: [{ phoneNumber: process.env.RINGCENTRAL_RECEIVER }] }), 'test.json')
formData.append('files[]', fs.createReadStream(path.join(__dirname, 'test.png')), 'test.png')
await rc.post('/restapi/v1.0/account/~/extension/~/fax', formData, {
  headers: formData.getHeaders()
})
  • 而不是headers: {'Content-Type': 'multipart/form-data' }我更喜欢headers: formData.getHeaders()
  • 我使用asyncawait以上,如果您不喜欢它们,可以将它们更改为普通的 Promise 语句
  • 为了添加您自己的标题,您只需 headers: { ...yourHeaders, ...formData.getHeaders() }

新增内容如下:

浏览器

浏览器FormData不同于 NPM 包“form-data”。以下代码在浏览器中对我有用:

HTML:

<input type="file" id="image" accept="image/png"/>

JavaScript:

const formData = new FormData()

// add a non-binary file
formData.append('files[]', new Blob(['{"hello": "world"}'], { type: 'application/json' }), 'request.json')

// add a binary file
const element = document.getElementById('image')
const file = element.files[0]
formData.append('files[]', file, file.name)
await rc.post('/restapi/v1.0/account/~/extension/~/fax', formData)
headers: formData.getHeaders() 是它为我工作的原因。谢谢。
2021-05-30 23:27:16
@laimison 谢谢,它对我有用。我已经更新了我的答案。
2021-06-04 23:27:16
我不是专家,但在我的情况下,我设法避免了使用多个文件上传的这些并发症(concat-streamasyncawait),for(var x = 0; x<this.state.files.length; x++) { formData.append('files[]', this.state.files[x]) }因此我可以使用axios.post(url, formData, config)
2021-06-06 23:27:16
@TylerLong 我在 FormData API 中找不到任何 getHeaders 方法。developer.mozilla.org/en-US/docs/Web/API/FormData
2021-06-16 23:27:16
非常感谢这个例子,很难弄清楚为什么多文件上传不起作用。
2021-06-19 23:27:16

2020 ES6 的做法

将 html 中的表单绑定到数据中,如下所示:

数据:

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

提交时:

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')
  }
}