公理张贴请求发送表单数据

Axios POST请求正在触发控制器上的 URL,但是将 null 值设置为我的 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);
});

浏览器回应:

enter image description here

如果我将标题设置为:

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

请求引发错误

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

如果我在邮递员中发出相同的请求,那么它工作得很好,并且为 POJO 类设置了值。

有人可以解释如何设置边界或如何使用公理发送表单数据。

932143 次浏览

你可以像这样使用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

上传(多个)二进制文件

node . 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: formData.getHeaders()而不是headers: {'Content-Type': 'multipart/form-data' }
  • 上面我使用了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)

查看变量的名称

你可以这样使用它:

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

上面的方法对我来说很有效,但因为这是我经常需要的东西,所以我使用了一个基本的方法来制作平面物体。注意,我也在使用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;
}

在我的例子中,我必须像下面这样将边界添加到中:

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,这个解决方案也很有用。

更直接的是:

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

在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),

import qs from 'qs';


const data = { 'bar': 123 };


const options = {


method: 'POST',


headers: { 'content-type': 'application/x-www-form-urlencoded' },


data: qs.stringify(data),


url, };


axios(options);

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

在我的例子中,问题是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
}
}

字段名的值;并不重要,除非有接收端处理需要它。

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

我还需要计算内容的长度

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

我需要使用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头文件!

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

试试这个,很管用

我在使用带有axios的FormDatahttps://apps.dev.microsoft.com服务进行调用时遇到了类似的问题,它错误地用“;请求体必须包含以下参数:'grant_type'"

重新格式化后的数据

{
grant_type: 'client_credentials',
id: '123',
secret: '456789'
}

"grant_type=client_credentials&id=123&secret=456789"

下面的代码起作用了:

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

对我来说,它使用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);
}

当需要从NodeJS环境中使用axios POST x-www-form- urlenencoded数据时,这应该工作得很好。您可能需要向配置中添加一个授权标头。如果端点需要身份验证,则返回头对象。

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));

在发送请求时设置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);
});