axios发送表单数据的请求

Sri*_*wda 132 ajaxform reactjs react-redux axios axios-cookiejar-support

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);
});
Run Code Online (Sandbox Code Playgroud)

浏览器响应:

在此输入图像描述

如果我将标题设置为:

headers:{
  Content-Type:'multipart/form-data'
}
Run Code Online (Sandbox Code Playgroud)

请求抛出错误

发布multipart/form-data时出错.Content-Type标头缺少边界

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

任何人都可以解释如何设置边界或如何使用axios发送表单数据.

Aaq*_*qib 211

您可以使用FormData()发布axios数据, 如:

var bodyFormData = new FormData();
Run Code Online (Sandbox Code Playgroud)

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

bodyFormData.set('userName', 'Fred');
Run Code Online (Sandbox Code Playgroud)

如果您要上传图片,则可能需要使用 .append

bodyFormData.append('image', imageFile); 
Run Code Online (Sandbox Code Playgroud)

然后你可以使用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);
    });
Run Code Online (Sandbox Code Playgroud)

你可以在这里阅读更多

  • 你需要使用append而不是set. (7认同)
  • bodyFormData.set不是我遇到此错误的函数 (6认同)
  • 你的配置对象是错误的。它应该是:`{ method: 'post', url: 'myurl', data: bodyFormData, headers: {'Content-Type': 'multipart/form-data' } }` (3认同)
  • 在nodejs中你需要`npm install --save form-data` (3认同)
  • bodyFormData.set这对我有用 (2认同)
  • bodyFormData.append对我有用 (2认同)

小智 26

查看查询字符串.

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

var querystring = require('querystring');
axios.post('http://something.com/', querystring.stringify({ foo: 'bar' }));
Run Code Online (Sandbox Code Playgroud)

  • 这不是表单数据。这是一种 url 编码的表单格式。 (11认同)
  • 在节点环境中,这甚至更好 (2认同)

Lui*_*ias 22

在我而言,我不得不将添加边界头部像下面这样:

const form = new FormData();
    formData.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}`,
        },
    });
Run Code Online (Sandbox Code Playgroud)

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

  • `FormData._boundary` 在 Chrome 76 和 Firefox 67 中均未定义,并且 [axios 无论如何都会删除 Content-Type 标头](https://github.com/axios/axios/blob/503418718f669fcc674719fd862b355605d7b41f/lib/adapters/xhr.js #L15-L17),所以这应该没有效果。 (4认同)
  • 当试图发布到imgur的api时,这解决了我的问题.在文档的任何地方都没有提到,但如果没有它,则会得到400无效的URL响应. (3认同)
  • 边界部分是我的代码中唯一缺少的东西,在节点中工作完美! (3认同)
  • 使用`boundary`请求正在工作。谢谢 (2认同)

Des*_*web 14

2020 ES6 的做法

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

数据:

form: {
   name: 'Joan Cap de porc',
   email: 'fake@email.com',
   phone: 2323,
   query: 'cap d\ou'
   file: null,
   legal: false
},
Run Code Online (Sandbox Code Playgroud)

提交时:

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')
  }
}
Run Code Online (Sandbox Code Playgroud)


Tyl*_*ong 9

上传(多个)二进制文件

当你想通过文件发布时,事情变得复杂multipart/form-data,特别是多个二进制文件.以下是一个工作示例:

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

const formData = new FormData()
formData.append('json', JSON.stringify({ to: [{ phoneNumber: process.env.RINGCENTRAL_RECEIVER }] }), 'test.json')
formData.append('attachment', fs.createReadStream(path.join(__dirname, 'test.png')), 'test.png')
formData.pipe(concat({ encoding: 'buffer' }, async data => {
  const r = await rc.post('/restapi/v1.0/account/~/extension/~/fax', data, {
    headers: formData.getHeaders()
  })
  console.log(r.data)
}))
Run Code Online (Sandbox Code Playgroud)
  • 而不是headers: {'Content-Type': 'multipart/form-data' }我喜欢headers: formData.getHeaders()
  • 我需要用来concat-stream连接多个文件流
  • 我使用asyncawait以上,如果您不喜欢它们,可以将它们更改为简单的Promise语句

  • 非常感谢这个例子,很难弄清楚为什么多个文件上传不起作用。 (2认同)
  • 我不是专家,但就我而言,我已经设法通过使用“for(var x = 0; x<this .state.files.length; x++) { formData.append('files[]', this.state.files[x]) }` 这样我就可以使用 `axios.post(url, formData, config)` 提交 (2认同)

lou*_*lyl 8

2022年的方式

Axios文档还没有更新,但是现在有一个方便的方法来制作formdata,就是使用axios.toFormData()方法。

这是它的 TypeScript 定义:

export function toFormData(sourceObj: object, targetFormData?: GenericFormData, options?: FormSerializerOptions): GenericFormData;
Run Code Online (Sandbox Code Playgroud)

例子:

const formData = axios.toFormData({"myField":"myValue"})

const response = await axios({
  method: "post",
  url: "...",
  data: formData,
  headers: { ... }
})
Run Code Online (Sandbox Code Playgroud)

来源:

您可以在 axios 的 Change log 中找到以下内容

[1.0.0] - 2022-10-04

为公开的 toFormData 帮助程序添加了通用 TS 类型#4668

添加了带有附加选项的增强型 toFormData 实现4704


小智 6

更直接:

axios.post('/addUser',{
    userName: 'Fred',
    userEmail: 'Flintstone@gmail.com'
})
.then(function (response) {
    console.log(response);
})
.catch(function (error) {
    console.log(error);
});
Run Code Online (Sandbox Code Playgroud)

  • 是的,看起来,如果没有文件上传,这是最简单的方法。 (5认同)

ABH*_*IRE 6

import axios from "axios";
import qs from "qs";   

const url = "https://yourapplicationbaseurl/api/user/authenticate";
    let data = {
      Email: "testuser@gmail.com",
      Password: "Admin@123"
    };
    let options = {
      method: "POST",
      headers: { "content-type": "application/x-www-form-urlencoded" },
      data: qs.stringify(data),
      url
    };
    axios(options)
      .then(res => {
        console.log("yeh we have", res.data);
      })
      .catch(er => {
        console.log("no data sorry ", er);
      });
  };
Run Code Online (Sandbox Code Playgroud)


s-h*_*ter 6

在使用FormData和 axios 调用https://apps.dev.microsoft.com服务时,我遇到了类似的问题,并且错误显示为“请求正文必须包含以下参数:'grant_type'

重新格式化数据后

{
  grant_type: 'client_credentials',
  id: '123',
  secret: '456789'
}
Run Code Online (Sandbox Code Playgroud)

"grant_type=client_credentials&id=123&secret=456789"
Run Code Online (Sandbox Code Playgroud)

并且以下代码有效:

const config: AxiosRequestConfig = {
    method: 'post',
    url: https://apps.dev.microsoft.com/auth,
    data: 'grant_type=client_credentials&id=123&secret=456789',
    headers: {
        'Content-Type': 'application/x-www-form-urlencoded',
    }
};

axios(config)
.then(function (response) {
  console.log(JSON.stringify(response.data));
})
.catch(function (error) {
  console.log(error);
});
Run Code Online (Sandbox Code Playgroud)

  • 你救了我!由于某种原因,使用“FormData”构建对象不起作用,但是当我按照您的建议执行“data: 'grant_type=client_credentials&id=123&secret=456789',”之类的操作时,它就成功了! (3认同)

小智 5

在 axios 中使用 application/x-www-form-urlencoded 格式

默认情况下,axios 将 JavaScript 对象序列化为 JSON。要改为以 application/x-www-form-urlencoded 格式发送数据,您可以使用以下选项之一。

浏览器

在浏览器中,您可以按如下方式使用 URLSearchParams API:

const params = new URLSearchParams();

params.append('param1', 'value1');

params.append('param2', 'value2');

axios.post('/foo', params);

请注意,并非所有浏览器都支持 URLSearchParams(请参阅 caniuse.com),但有一个 polyfill 可用(确保 polyfill 全局环境)。

或者,您可以使用 qs 库对数据进行编码:

const qs = require('qs');

axios.post('/foo', qs.stringify({'bar': 123 }));

或者以另一种方式(ES6),

从'qs'导入qs;

const 数据 = { 'bar': 123 };

常量选项 = {

方法:'POST',

标头:{'内容类型':'应用程序/x-www-form-urlencoded'},

数据:qs.stringify(数据),

网址,};

axios(选项);


Nat*_*hew 5

发送请求时设置边界(服务器使用该边界来解析有效负载) 在发出请求之前您无法获取边界。因此,获得此信息的更好方法是使用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);
  });

Run Code Online (Sandbox Code Playgroud)