Axios发送POST请求以发送表单数据

445

当我使用axios POST请求控制器的网址时,它会将空值设置为我的POJO类,但是当我通过谷歌开发者工具查看有效负载时,它包含数据。我做错了什么?

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

请求发生错误

提交multipart/form-data时出错。缺少Content-Type头信息的boundary属性

如果我在postman中发送相同的请求,一切都很正常,并且将值设置到我的POJO类中。

有人可以解释一下如何设置boundary或者如何使用axios发送表单数据吗?


这与React和Redux有什么关系?我们能不能只用通用的JS来实现? - ggorlen
20个回答

5

当请求被发送时,服务器使用boundary(用于解析有效载荷)进行设置。在发送请求之前,您无法获取边界。因此,更好的方法是使用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);
  });


1
它对我来说只需要'Content-Type': 'multipart/form-data'就可以运行。 - parsecer

3

我需要计算内容长度。

const formHeaders = form.getHeaders();
formHeaders["Content-Length"] = form.getLengthSync()

const config = {headers: formHeaders}

return axios.post(url, form, config)
.then(res => {
    console.log(`form uploaded`)
})

没有这个,我就无法得到响应。谢谢。 - PravyNandas

2

我需要使用 axios 一次上传多个文件,由于 FormData API 的原因,我遇到了一些困难:

// const instance = axios.create(config);

let fd = new FormData();
for (const img of images) { // images is an array of File Object
  fd.append('images', img, img.name); // multiple upload
}

const response = await instance({
  method: 'post',
  url: '/upload/',
  data: fd
})

我没有指定 content-type: multipart/form-data 头部!


0

上述方法对我有用,但由于我经常需要使用它,所以我使用了一种基本方法来处理平面对象。注意,我当时正在使用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;
}

objectToFormData未定义,而formData在for循环外返回,但在for循环内定义。formData很容易理解,但是objectToFormData应该是什么呢? - Trevor
我认为这应该是函数的名称,因为它旨在是递归的,所以我假设你可以将objectToFormData更改为packageData或反之亦然。 - Raymond Ativie

0

对我来说,使用axios、typescript和form-data(v4.0.0)可以解决问题:

import FormData from "form-data";
import axios from "axios";

async function login() {
  var data = new FormData();
  data.append("User", "asdf");
  const return = await axios.post(
    "https://ptsv2.com/t/1q9gx-1652805776/post", data,
    { headers: data.getHeaders() }
  );
  console.log(return);
}

0

在 NodeJS 环境中使用 axios 发送 x-www-form-urlencoded 数据时,这应该能够很好地工作。如果端点需要身份验证,则可能需要将 Authorization 标头添加到 config.headers 对象中。

const config = {
  headers: {
    accept: 'application/json',
    'cache-control': 'no-cache',
    'content-type': 'application/x-www-form-urlencoded'
  }

const params = new URLSearchParams({key1: value1, key2: value2});

return axios
  .post(url, params.toString(), config)
  .then((response) => {
    return response.data;
  })
  .catch((error) => console.error(error));

0
在最新的axios版本中,你可以使用以下方法发送一个post表单数据:
axios.postForm(url, data);

它将会产生与在表单实例中逐个创建相同的结果。
var bodyFormData = new FormData();
bodyFormData.append("abc", "xyz");

你可以在axios文档中查看更多相关信息:https://axios-http.com/docs/multipart

-1
在我的情况下,问题是FormData附加操作的格式需要填写额外的“选项”参数来定义文件名,如下所示:
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与浏览器的form-data不太兼容。 - Игор Ташевски

-2
 transformRequest: [
  function(data, headers) {
    headers["Content-Type"] = "application/json";
    return JSON.stringify(data);
  }
]

试试这个,它有效


-2

https://www.npmjs.com/package/axios

它正在运作

// "content-type": "application/x-www-form-urlencoded", // 提交此内容

import axios from 'axios';

let requestData = {
      username : "abc@gmail.cm",
      password: "123456"
    };
   
    const url = "Your Url Paste Here";

    let options = {
      method: "POST",
      headers: { 
        'Content-type': 'application/json; charset=UTF-8',

        Authorization: 'Bearer ' + "your token Paste Here",
      },
      data: JSON.stringify(requestData),
      url
    };
    axios(options)
      .then(response => {
        console.log("K_____ res :- ", response);
        console.log("K_____ res status:- ", response.status);
      })
      .catch(error => {
        console.log("K_____ error :- ", error);
      });

获取请求

fetch(url, {
    method: 'POST',
    body: JSON.stringify(requestPayload),           
    headers: {
        'Content-type': 'application/json; charset=UTF-8',
        Authorization: 'Bearer ' + token,
    },
})
    // .then((response) => response.json()) .  // commit out this part if response body is empty
    .then((json) => {
        console.log("response :- ", json);
    }).catch((error)=>{
        console.log("Api call error ", error.message);
        alert(error.message);
});

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接