我今天花了几个小时试图获得一个发布请求,以使用一些参数和一个我需要上传的文件。
我能够使其与纯 javascript 和 XMLHttpRequest 一起使用,但它不适用于 Axios。 我究竟做错了什么?
下面是使用 XMLHttpRequest 工作的代码:
let data = new FormData();
data.append('action', 'ADD');
data.append('param', 0);
data.append('secondParam', 0);
data.append('file', new Blob([payload], { type: 'text/csv' }));
// this works
let request = new XMLHttpRequest();
request.open('POST', url);
request.send(data);
那会是什么“Axios”版本?
这是我的尝试之一(简单的):
// this won't work
const config = { headers: { 'Content-Type': 'multipart/form-data' } };
axios.post(url, data, config)
.then(response => console.log(response))
.catch(errors => console.log(errors));
谢谢! 感谢您与 Axios 的出色合作!
代码对我来说看起来不错。 (你不需要设置 Content-Type,但这并不重要。)当你尝试通过 axios 发送请求时会发生什么?
我注意到设置 Content-Type 与否不会改变这种情况下的任何内容。 当我尝试使用 Axios 发送请求时,数据似乎是一个空字符串,因此后端将响应与缺少参数相关的错误。
我使用的是 0.9.1,但问题在 0.11.0 上仍然存在。
如果还有什么我可以做的来帮助调试这个,请告诉我,好吗?
谢谢@nickuraltsev !
您能否在 Chrome 开发工具网络面板中查看您的请求的外观,并在可能的情况下提供屏幕截图?
@nickuraltsev看看这是否有帮助:
我认为请求标头是错误的。
所以没有请求有效载荷?
好吧,我们应该有,但数据是一个空字符串。 我不知道是什么破坏了它(考虑到我在第一篇文章中分享的代码)。
我知道了。 并且在开发工具中没有针对您的请求的请求有效负载部分,对吗?
可能相关的标题问题。 当内容类型在请求的配置对象中设置时,它被连接起来,例如
axios.post(
'https://example.com/login',
{emailAddress:电子邮件,密码:hashedPassword},
{标头:{'内容类型':'应用程序/json'}}
);
标头内容类型为 application/json,application/json
在这种情况下不会解析正文
@nickuraltsev对! 您在该屏幕截图上看到的就是我在开发工具上的全部内容。
@rrapant可能是对的,但我几乎可以肯定设置'Content-Type'
或不设置,至少在这种情况下,并没有改变任何东西。 我必须再次检查才能确定。
@rrapant重复内容类型值的问题已由#317 修复。 该修复将包含在下一个版本中。 谢谢!
@rafaelbiten我刚刚尝试重现该问题,但无济于事。 我使用了以下代码:
const data = new FormData();
data.append('action', 'ADD');
data.append('param', 0);
data.append('secondParam', 0);
data.append('file', new Blob(['test payload'], { type: 'text/csv' }));
axios.post('http://httpbin.org/post', data);
数据成功发送到服务器:
@rafaelbiten您能否尝试使用 FromData 向http://httpbin.org/post发送请求,就像我的代码片段中一样?
暂时关闭这个。 如有必要,请随时重新打开。
嗨@nickuraltsev ,我遇到了同样的问题。
var fd = new FormData();
fd.append('file', this.refs.multipartfiles.files[0]);
const config = { headers: { 'Content-Type': 'multipart/form-data' } };
axios.post('/dataAPI/sendFile', {
"UploadCommand": fd
}, config)
.then(function (response) {
console.log(response);
})
.catch(function (error) {
console.log(error);
});
请在下面找到我的标题信息的屏幕截图,
我有一个问题,_axios是否支持向节点服务器发送多部分数据文件?_
@Sreekhar我不知道它是否会起作用,但是您是否可以将 FormData 添加为第二个参数而不是将其包装在另一个对象中?
axios.post('/dataAPI/sendFile', fd, config)
如果你需要使用'UploadCommand'作为文件所在部分的名称,你需要使用这个fd.append('UploadCommand', this.refs.multipartfiles.files[0]);
@yungpanda我找到了一个替代方案。 我想我现在必须重新创建 API。 无论如何,我会尝试检查它是否有效,我会保持线程更新。 感谢您的回复。
@Sreekhar将 Content-Type 设置为 undefined 以让浏览器将其更改为 multipart/form-data 并自动添加边界
@nickuraltsev这是一个在节点上不起作用的最小示例:
const data = new FormData();
data.append('action', 'ADD');
data.append('param', 0);
data.append('secondParam', 0);
axios.post('http://httpbin.org/post', data).then(req => {
console.log('Req done: ', req)
}).catch(err => {
console.error('Error: ', err)
})
错误:结束后写入
@krzkaczor您是否找到了使用 axios 发送 multipart/form-data 的任何解决方法?
@PierreCavalet不,我用request-promise
代替。
@krzkaczor谢谢,也被迫切换
@krzkaczor如果您还没有这样做,请尝试添加内容类型
const config = { headers: { 'Content-Type': 'multipart/form-data' } };
let fd = new FormData();
fd.append('file',files[0])
return axios.post("http://localhost:5000/upload", fd, config)
@krzkaczor我也面临与 axios 和 multipart/form-data 相同的问题。 您能否发布您在 request-promise 中使用的代码的要点。
@dan-boa 你去: https ://gist.github.com/krzkaczor/bdbe09d4096b051a3c18387c4ca79a06 它还展示了如何将字符串作为文件发送(设置路径)
如果有人想知道,这里有一个如何将FormData
与axios
一起使用的示例。 您基本上必须将数据流式传输到缓冲区并传递正确的标头。
const concat = require("concat-stream")
const fd = new FormData()
fd.append("hello", "world")
fd.append("file", fs.createReadStream(file))
fd.pipe(concat(data => {
axios.post("/hello", data, {
headers: fd.getHeaders()
})
}))
我有同样的问题(在浏览器中,而不是在节点中)。 事实证明,如果您根本不设置Content-Type
标头并让 axios 解决问题,它会起作用(还要检查您是否也没有将该标头设置为 axios 拦截器中的默认值。如果您需要一些其余 API 调用的默认值,您可以为 FormData() 请求创建一个单独的 axios 实例)
当我尝试上传到另一个远程服务器时,我最终在节点端使用了 request-promise。
出于同样的原因,我切换到了 request-promise。 否则爱 axios!
@guncha您的示例在 0.15.3 中为我工作,直到我尝试上传一个二进制文件,该文件最终被编码为 UTF8。 告诉 concat 使用缓冲区解决了这个问题。
const concat = require("concat-stream")
const fd = new FormData()
fd.append("hello", "world")
fd.append("file", fs.createReadStream(binaryFile))
fd.pipe(concat({encoding: 'buffer'}, data => {
axios.post("/hello", data, {
headers: fd.getHeaders()
})
}))
或者,我会使用一个承诺:
const promise = new Promise((resolve) => {
const fd = new FormData();
fd.append("hello", "world");
fd.append("file", fs.createReadStream(binaryFile));
fd.pipe(concat({ encoding: 'buffer' }, data => resolve({ data, headers: fd.getHeaders() })));
});
promise.then(({ data, headers }) => axios.post('/hello', data, { headers }));
const callApi = (url, params) => {
const formData = new FormData()
for(let name in params) {
let param = params[name]
if (typeof param === 'object') {
param = JSON.stringify(params[name])
}
formData.append(name, param)
}
return axios.post(url, formData)
.then(response => {
console.log(response)
})
}
@guncha为我工作。 谢谢
同样的问题在这里
只需将边界添加到Content-Type
:
const request = require('axios');
const FormData = require('form-data');
const fs = require('fs');
let data = new FormData();
data.append('file1', fs.createReadStream('./image1.jpeg'), 'image1.jpeg');
data.append('file2', fs.createReadStream('./image2.jpeg'), 'image2.jpeg');
let options = {
method: 'POST',
url: 'http://localhost:3200/upload',
headers: {
'Content-Type': `multipart/form-data; boundary=${data._boundary}`
},
data
};
return request(options)
.then(response => {
console.log(response);
});
嘿,
我得到了这个 json 格式的文件,谁能帮我把它转换成多部分文件。
使用的平台是java8。
"body": "------WebKitFormBoundaryQsJGeBuR8e9dQ4Pm\r\nContent-Disposition: form-data; name=\"file\"; filename=\"backup prolog.txt\"\r\nContent-Type: text/plain\r\n\r\n%All the Pre-Defined relations\r\nconnected(hira,rohit,father).\r\nconnected(rohit,rakesh,father).\r\nconnected(ram,hira,father).\r\nconnected(kavri,hira,mother).\r\nconnected(hira,kavri,son).\r\nconnected(arun,vinayak,father).\r\nconnected(vinayak,arun,son).\r\nconnected(arun,shashi,husband).\r\nconnected(shashi,arun,wife).\r\nconnected(vinayak,vardaan,brother).\r\nconnected(vardaan,vinayak,brother).\r\nconnected(shashi,vinayak,mother).\r\nconnected(vinayak,shashi,son).\r\n\r\n\r\n\r\nconnected2(X,Y,D) :- connected(X,Y,D).\r\n%connected2(X,Y,D) :- connected(Y,X,D).\r\n\r\nnext_node(Current, Next,R, Path) :-connected2(Current, Next, R),not(member(Next, Path)).\r\n\r\nfunc(how,is,X,related,to,Y):-depth_first(X,Y,[X],P),write(P).\r\n%Procedure to Start the depth_first\r\ndepth_first(Goal, Goal, _, [Goal]).\r\n\r\ndepth_first(Start, Goal, Visited, [Start,is,R,of|Path]) :-next_node(Start, Next_node,R, Visited),depth_first(Next_node, Goal,[Next_node,R|Visited], Path).\r\n\r\n\r\n\r\n\r\n\r\n\r\n------WebKitFormBoundaryQsJGeBuR8e9dQ4Pm--\r\n"
谢谢
代码在浏览器中有效,但在节点上无效。
const fdata = new FormData();
fdata.append('user', u);
fdata.append('hostnames', n.join(' '));
const host = localStorage.getItem('host');
const port = localStorage.getItem('port');
axios({
url: `http://${host}:${port}/hosts/remove`,
method: 'post',
data: fdata
}).then(response => {
if (response.status === 200) {
console.log(response.data);
console.log('Removed host successfully');
}
return null;
}).catch(er => console.log(er));
嗨@Sreekhar
对我来说,我将配置更改为const config = { headers: { 'Content-Type': 'application/json' } };
它工作得很好
请重新打开,直到有一些一致的答案/工作流程。 似乎很多人仍然遇到这个问题。
+1 重新打开
包含二进制文件数据的 HTTP 帖子似乎在 axios v0.16.2 中运行良好
// The following was tested successfully with axios v0.16.2
// Create a new form. Note: could also specify an existing form as
// the parameter to the FormData() constructor to copy all the elements
// from the existing form to the new one being created.
var tempFormData = new FormData();
var someNoteValue = 'Hello World';
var someAudioData = []; // populate this with data from file, with MediaRecorder() etc.
// Add form fields
tempFormData.set('SomeNote', 'Hello World');
tempFormData.set('SomeRecording', someAudioData[0], 'SampleRecording.webm');
// Optional: output list of form fields to the console for debugging
for (var pair of tempFormData.entries()) {
console.log('Form field: ' + pair[0] + ', ' + pair[1]);
}
// Call Axios to post the form to myurl
axios({
method: 'post',
url: 'myurl',
data: tempFormData,
config: { headers: {'Content-Type': 'multipart/form-data' }}
})
.then(function (response) {
//handle success
console.log(response);
})
.catch(function (response) {
//handle error
console.log(response);
});
}
此外,当使用缓冲区表示文件时,这对我有用:
const form = new FormData();
const fileBuffer = new Buffer(
'MM2 - noticeably shallower than the original - score: 101%', 'utf-8'
);
form.append('name', 'reviews.txt'); // additional form data field
form.append('file', fileBuffer, 'original-file-name.bar');
const res = await axios.post(`/uploadfile`, form, { headers: form.getHeaders() });
需要注意的重要一点:如果您在 Axios 实例的默认值中设置了任何默认数据参数,则上述任何解决方案都不起作用。 您还可以检查您是否在 Axios 实例中指定了默认的 Content-Type 标头(通过 axios.defaults.headers 和 axios.defaults.parameters)。
这可能不是重点,但问题可能与在服务器端使用body-parser
有关。 我正在努力解决类似的问题并遇到了这篇文章:
https://philna.sh/blog/2016/06/13/the-surprise-multipart-form-data/
TL;DR - body-parser
不处理多部分/表单数据。 换句话说, axios
不是问题, body-parser
是。 这可能就是上述缓冲溶液起作用的原因。
我认为此功能是出于安全原因,如此处所述:
http://andrewkelley.me/post/do-not-use-bodyparser-with-express-js.html
我希望对某人有所帮助!
我有同样的问题。 我使用 Axios 0.16.2
并通过XMLHttpRequest
发送有效,但不是通过 Axios。
我有基本的 FormData 对象:
常量 formData = new FormData();
formData.append('name', 'textName');
我尝试了@Janekk的建议:
axios({
method: 'post',
url,
withCredentials: true,
data: { formData },
})
然后@faalkhah的建议:
const config = { headers: { 'Content-Type': 'application/json' } };
axios({
method: 'post',
url,
withCredentials: true,
data: { formData },
config,
})
或@askona的建议:
const config = { headers: { 'Content-Type': undefined } };
axios({
method: 'post',
url,
withCredentials: true,
data: { formData },
config,
})
请求标头为application/json
且formData
为空。
我不知道如何尝试@demeter-macik 修复,因为它似乎只适用于后端https://stackoverflow.com/a/13454425/968379
大家好,
我也有同样的问题
我在客户端的代码
`
const url = '/file/uploadTest';
const formData = new FormData();
formData.append('file', file);
formData.append('params1', value);
formData.append('params2', value2)
const config = {
headers: {
'Content-Type': 'multipart/form-data',
}
}
axios.post(url,formData,config)`
在 Sails 服务器中,我登录控制台 req.body
我发现,当我调用请求 10 次时,服务器大约有 3 4 次没有收到正文(正文为空)。
我检查了 chrome 的 devtool,请求仍然在有效负载中传输文件和正文。
我还没有弄清楚为什么,但我有一个解决方案
`代码
const url = '/file/uploadTest';
const formData = new FormData();
formData.append('file', file);
formData.append('params1', value);
formData.append('params2', value2)
const config = {
headers: {
'Content-Type': 'multipart/form-data',
'params1': value,
'params2': value2
}
}
axios.post(url,formData,config)`
嗨@Sreekhar ,
你解决问题了吗? 我没有找到解决方案,请有人帮助我。
另外,提前谢谢你
你好,
我一直在尝试发布 multiformdata(它是一个 Eztext SMS api)
将 axios 与 node.js 一起使用。
它适用于以下代码,
返回新的承诺(功能(解决,拒绝){
var request = require("request");
var options = {
method: 'POST',
url: 'https://app.eztexting.com/sending/messages',
qs: {format: 'json'},
formData:
{
User: '**',
Password: '**',
'PhoneNumbers[0]': '8572222***',
Message: 'Appointment Reminder',
MessageTypeID: '1'
}
};
request(options, function (error, response, body) {
if (error) {
console.log(error);
reject(error);
}
else {
console.log(response);
resolve(response);
}
// console.log(body);
});
但它不适用于 axios,因为没有发送 SMS,但我得到以下请求的状态代码为 200:-
var axios=require('axios');
axios.post('https://app.eztexting.com/sending/messages', {
qs: { format: 'json' },
headers: {
'Content-Type': 'application/x-www-form-urlencoded'
},
formData:
{ User: '****',
Password: '2sH****5',
'PhoneNumbers[0]':'85722******',
Message: 'Hello Yahska',
MessageTypeID: 1 }
})
.then(function (response) {
console.log(response);
})
.catch(function (error) {
console.log(error);
});
为什么发布请求在“请求”库而不是 Axios 中成功?
您是否尝试过在不设置任何标题的情况下将数据从 JSON 转换为 FormData?
应自动处理数据的标头(即除了身份验证标头之外)
async function sendMessage(myJSONPayload){
try{
const data = convertJSON2FormData(myJSONPayload);
const response = await axios.post('https://app.eztexting.com/sending/messages', {
data
});
console.log(response);
} catch(ex){
console error(err);
}
}
sendMessage ({ User: '****',
Password: '2sH****5',
'PhoneNumbers[0]':'85722******',
Message: 'Hello Yahska',
MessageTypeID: 1 }
});
对于从 JSON 到 FormData 的转换,请使用类似于此答案的内容
请记住,嵌套键很难处理。 例如,当我们将数据发送到我们的后端时,如果我们像这样将它们展平,它就可以工作:
{a: {b: 2}} --> formData.append("a.b",2)
同样的问题。
当然,@michaelscheurer! 设置请求的标头是不够的:您必须提交 FormData 才能使其工作。 它是一个浏览器对象,它将使用所有适当的边界进行序列化以处理请求......无论是 axios 还是 vanilla js 都不会为您将 JSON 数据转换为 FormData。 Axios 会识别它是一个 FormData 并为你设置标题,所以你不需要设置它们
尝试按照我之前的答案提示...
@Iamuertepeluda
我按照您的建议尝试了以下操作,但没有运气,,,与我获得状态 200 ok 的行为相同,但没有通过以下请求发送 SMS
var axios=require('axios');
const FormData = require('form-data');
const form = new FormData();
//fo this jason I created a form
// formData:
// {
// User: '*****',
// Password
// :
// '******',
// 'PhoneNumbers[0]'
// :
// '8****2763',
// Message
// :
// 'Appointment Reminder',
// MessageTypeID
// :
// '1'
// }
form.append('User','****');
form.append('Password','*****');
form.append('PhoneNumbers[0]','*****');
form.append('Message','Appointment Reminder');
form.append('MessageTypeID','1');
axios.post('https://app.eztexting.com/sending/messages', form,
{
qs: {format: 'json'},
headers:
{
'content-type'
:
'multipart/form-data; boundary=----WebKitFormBoundary7MA4YWxkTrZu0gW'
}
}
)
.then(function (response) {
console.log(response);
})
.catch(function (error) {
console.log(error);
});
@Ruchi2729您使用的是 node.js 还是浏览器?
在浏览器中你不需要const FormData = require('form-data');
因为 FormData 是本机的。
此外尝试不设置标题和 qs,或尝试
axios.request({
url: "https://app.eztexting.com/sending/messages"
type: "post",
data: form //the instance of FormData of your stub
});
正如我提到的,它应该在浏览器中自动设置标题
@Ruchi2729我看到您正在使用节点,抱歉。
我记得曾经在 axios 上使用过form-data
,但我不记得它是否真的有效。
但是您确定这是使用 eztexting 发送 SMS 的正确方式吗? 从他们的文档来看,它似乎有所不同,就像您应该使用 api 密钥和他们自己的节点客户端......
我们可以重新打开它吗? 看起来很多人仍然反对这一点,包括我自己。 例如,此请求不会通过 axios 按预期发送到服务器,但如果我通过 Postman 发送与multipart/form-data
相同的文件,则一切正常。
编辑:我的问题是尝试将 base64 编码的数据 uri 作为表单数据发送。 如果其他人正在努力解决同样的问题,这里有一些示例代码来转换它:
async function importCsv(data: CsvImportData): Promise<void> {
const formData = new FormData();
const headers = {'Content-Type': 'multipart/form-data'};
formData.append('csv', dataURItoFile(data.file, `upload_${Date.now()}.csv`));
try {
await axios.post('https://example.com/api/upload/csv', formData, {headers});
} catch(e) {
console.error(e);
}
}
function dataURItoFile(dataURI: string, defaultFileName: string): File {
let byteString: string;
const [metadata, data] = dataURI.split(',');
if (/base64$/.test(metadata)) {
byteString = atob(data);
} else {
byteString = unescape(data);
}
const mimetype: string = metadata.split(':')[1].split(';')[0];
const filename: string = (metadata.match(/name\=(.*);/) || [])[1] || defaultFileName;
let dataView: Uint8Array = new Uint8Array(byteString.length);
for (let i = 0; i < byteString.length; i++) {
dataView[i] = byteString.charCodeAt(i);
}
return new File([dataView], filename);
}
嘿,我指的是这份文件:- https://www.eztexting.com/developers/sms-api-documentation/rest#Sending
您指的是哪个文档以获取 API 密钥和所有内容?
@Ruchi2729
抱歉,我与Nexmo 混淆了,Nexmo 是另一种短信服务,有自己的节点客户端😅
但是无论如何,根据您提到的文档,您可以通过将format
设置为json
来避免 FormData 并让 axios 发送 JSON 有效负载(您可以让它通过有效负载格式隐式猜测标头)
https://app.eztexting.com/sending/messages?format=json
我想承认这一点的时间更长,所以希望这对某人有所帮助。 我正在使用 axios、express 和 express-fileupload。 我可以使用已附加到 FormData 的参数成功上传到 Node。 我使用 req.files 获取文件,然后使用 req.body['yourfilename'] 获取其余的表单数据
服务器(快递):
router.post('/helper/amazon/upload', function(req, res) {
if (!req.files) {
return res.status(400).send('No files were uploaded.')
}
console.log(req.body.filename);
return console.log(req.files);
前端(axios)
const formData = new FormData();
formData.append('file', this.validFile);
formData.append('filename', 'trails/' + this.$route.params.id.split('-')[0] + '/camping/');
axios.post(
/api/helper/amazon/upload , formData, {
headers: {
'Content-Type': 'multipart/form-data'
}
});
结果:
我有同样的问题,我可以看到我用我的开发工具成功发送了文件数据,但是在我的控制器里面我的 $request->file('file') 是空的
我的组件
提交表格() {
this.formData =new FormData();
this.formData.append('file',this.$refs.file.files[0]);
this.formData.append('分析',this.analyticsForm.analysis);
this.formData.append('_method','PATCH');
axios.post('/分析',
this.formData
,{headers: {'Content-Type': 'multipart/form-data'}}).then(response => this.isSubmittedRedirect(false,'/sources/'+this.source+'/description'+'') )
.catch((错误) => console.log(错误))
},
我发现用 FormData 做任何事情都是一个问题,因为 MVC 似乎不喜欢以这种方式获得任何东西,因为您必须将 Content-Type 指定为multipart/form-data
并且当我会抛出异常时检查if (!Request.Content.IsMimeMultipartContent()) { throw new HttpResponseException(HttpStatusCode.UnsupportedMediaType); }
,正如微软网站所说的那样: https ://docs.microsoft.com/en-us/aspnet/web-api/overview/advanced/sending-html-form-data-part-
最好只是将我的文件放入 base64 字符串:
https://stackoverflow.com/questions/37134433/convert-input-file-to-byte-array/49676679#49676679
这篇文章可能与如何做到这一点更相关,因为我在这个例子中使用了 DropZone:
https://stackoverflow.com/questions/32556664/getting-byte-array-through-input-type-file/49660172#49660172
我在这里更详细地介绍了它: https ://stackoverflow.com/questions/47574218/converting-from-blob-to-binary-to-save-it-to-mongodb/49660839#49660839
然后我可以创建一个 JSON 对象:
const myObj = {
file = myBase64String,
title = "myfileTitle.jpg"`
type = "image/jpeg"`
}
我没有使用 axios,而是使用了 XMLHttpRequest。
const xhr = new XMLHttpRequest();
并打开并设置标题:
xhr.open('POST', '/api/FileUpload/Post', true);
xhr.setRequestHeader('Content-Type', 'application/json;charset=UTF-8' );
xhr.withCredentials = true;
我设置了onreadystatechange
来捕获响应:
xhr.onreadystatechange = (response) =>
if (xhr.readyState === 4 && xhr.status === 200) {
console.log(response.target.responseText);
}
}
并且寄出:
xhr.send(JSON.stringify(myObj));
如果你使用 axios,它可能是:
try {
var axios = require('axios');
const config = {
headers: {
'Content-Type': 'application/json;charset=UTF-8',
}
}
await axios.post('https://example.com/api/upload/post', myObj, config)
.then(function (response) {
console.log(response);
})
.catch(function (error) {
console.log(error);
});
}
catch(e) { console.log(e); }
在 MVC 方面,您需要一个匹配模型:
public class MyModel {
public string file { get; set; }
public string title { get; set; }
public string type { get; set; }
}
然后将其作为带有 [FromBody] 标签的 Post 调用中的参数:
[System.Web.Http.HttpPost]
public virtual JsonResult<string> Post([FromBody]MyModel myModelObject)
{
string strBase64FileString = myModelObject.file;
string strTitle = myModelObject.title;
string strFileType = myModelObject.type;
return Json(JsonConvert.SerializeObject(new { file = myModelObject.file, title = myModelObject.title, myModelObject.type }));
}
你应该取回你发送的东西。 请注意,如果您将此作为测试实现,请使用非常小的文件执行此操作,这样您就不会永远等待锁定系统的浏览器/内存的可能性。
@navyjax2
我像你说的那样做,它正在处理小文件,但我需要发送大文件(> 250Mo),是的,它锁定了我的浏览器
是的,为此,您可能希望将文件数组分成可管理大小的块并以块的形式发送,在另一端(服务器端)有一个可以重新组合它们的方法,并给它一个参数以便它知道它是哪个块(第一个、第二个、第三个等)以及在它在服务器端处理文件之前期望的总块数。 但我认为,无论你做什么,对于这么大的文件,你都必须等待它完成它的工作。 如果你以块的方式进行内存管理,也必须小心内存管理,因为你必须确保每次都清除或重新使用你的变量,而不是每次都重新实例化相同变量的新版本你做一个块。 少数几个全局变量之一是好的 - 或者每次运行都设置为模型字段。
我同意@epferrari ,请考虑重新打开这个问题。
可以在 chrome 中使用 FormData 发送 base64 字符串,但无法使用 node(v8.9.3) 中的 axios 完成它。
它适用于节点获取......
const fetch = require('node-fetch')
const axios = require('axios')
const FormData = require('form-data')
const base64Img = require('base64-img')
const b64 = base64Img.base64Sync('./test.jpg').split('base64,')[1]
const form = new FormData()
form.append('b64_data', b64)
const headers = form.getHeaders()
// with node-fetch it worked
fetch('http://some.url', {
method: 'POST',
body: form,
headers,
}).then(res => res.text()).then(console.log).catch(console.log)
// not working with axios
axios({
method: 'POST',
url: 'http://some.url',
data: form,
headers,
}).then(console.log).catch(console.log)
=== 更新 ===
我不明白,我对 node-fetch 和 axios 使用相同的标头,并且似乎它们将相同的表单数据发布到服务器,为什么它们最终会有所不同?
顺便说一句,我发布的真实网址来自这里,我正在做的是用 nodejs 模拟浏览器的 http 请求,将图像发送到服务器并返回链接。
我通过使用解决了这个问题:
<input onChange="emitImageInfo(this)" type="file" multiple>
function emitImageInfo($event){
let files = $event.target.files
let formData = new FormData();
for (let i = 0; i < files.length; i++)
formData.append('image[' + i + ']', files[i])
axios.post('file/upload', formData)
.then((result) => { console.log('got it') })
.catch((err) => { console.log(err) })
}
这有效:
axios.post(localhost:3000/items, formData, { headers: { 'Content-Type': 'multipart/form-data' }});
我也有同样的问题
不使用 golang
就在Vue里找个简单的方法,不过我觉得可以用在其他情况下。😀
后端:Express.js 和 express-fileupload 包。
<template>
<div>
<input type="file"
name=""
id="file-upload"
multiple
@change="filesChange($event.target.files)">
<button @click="handleSubmit">Send</button>
</div>
</template>
<script>
export default {
data() {
return {
formData: new FormData(),
};
},
methods: {
filesChange(fileList) {
// First: append file to FormData
Array.from(Array(fileList.length).keys()).map(x => {
this.formData.append(fileList[x].name, fileList[x]);
});
},
handleSubmit() {
// Append Text
this.formData.append('username', 'Jeremy');
// Append Number: Will be string
this.formData.append('number', 9527);
// Append Array: Need to be converted to a string
this.formData.append('arrData', JSON.stringify([1, 2, 3]));
// Append Array: Need to be converted to a string
this.formData.append(
'objData',
JSON.stringify({ name: 'Jeremy', age: 28 })
);
this.axios({
method: 'post',
url: `file/multi-users`,
data: this.formData,
}).then(res => {
console.log(res);
});
},
},
};
</script>
即使我们面临同样的问题。 从 react java 脚本中删除了 content 类型的标头,然后它就可以正常工作了。 早些时候,当您在内容类型中明确设置时,没有设置边界
编辑:在进一步阅读之后,似乎 Express 是我的问题。 希望这对其他人有用
这里同样的问题。 @nickuraltsev强烈建议重新打开该问题。
我正在尝试使用以下代码通过 axios 将文件发布到我的节点服务器:
let ff = new FileReader();
ff.onload = (ev) => {
var result = ev.target.result;
console.log(`result: ${result} of type ${typeof(result)}`);
axios.post('/test', {
file: result
})
.then((response) => {
console.log(`Response: ${response}`)
})
.catch((err) => {
console.log(`Test error: ${err}`);
})
}
var sampleFile = //getting the file here
ff.readAsArrayBuffer(sampleFile);
请求的正文在服务器端完全是空的
尝试直接发送文件,将文件读取为 ArrayBuffer 并将文件读取为文本(尽管有效负载太大),但所有 3 个都不起作用。
两年后:
同样的问题...
@demeter-macik 谢谢,添加边界对我有用:微笑:
const form = new FormData();
form.append('email', '[email protected]');
form.append('phone_no', '63');
form.append('phone_code', '9179303100');
if (logo) {
form.append('logo', logo);
}
const response = await axios({
method: 'post',
url: `${apiUrl}users`,
data: form,
headers: {
'content-type': `multipart/form-data; boundary=${form._boundary}`,
},
});
这绝对适合我——所有浏览器,包括 Safari iOS。
我的代码是这样的:
功能示例发布(配置){
// save reference this
let that = this;
// can optionally pull in form fields from an existing HTML form)
let myForm = document.getElementById('myForm');
let myFormData = new FormData(myForm);
// add in data from config.data if applicable
if (config && config.data) {
that.objToStr(config.data, '', myFormData);
for (let n2 in config.data) {
if (config.data.hasOwnProperty(n2)) {
myFormData.set(n2, config.data[n2]);
}
}
}
if (config.binaryFiles && config.binaryFiles.length > 0) {
for (let i = 0; i < config.binaryFiles.length; i = i + 1) {
let thisFile = config.binaryFiles[i];
myFormData.append(thisFile.fieldName, thisFile.binaryData, thisFile.fileName)
}
}
let axiosConfig = {
method: 'post',
url: config.url,
data: myFormData,
onUploadProgress: config.onUploadProgress,
};
if (config && config.binaryFiles && config.binaryFiles.length > 0) {
axiosConfig.headers = {'Content-Type': 'multipart/form-data'};
}
else {
axiosConfig.headers = {'Content-Type': 'application/x-www-form-urlencoded'};
}
const ax = axios.create();
// note that passing in config to the constructor is broken as of axios v0.19.0-beta.1
// So we work around by passing in config to the request() method
ax.request(axiosConfig)
.then(function (response) {
// handle success
alert(response.data);
})
};
// 调用 samplePost 上传
样本邮递({
url: 'async',
data: {somefield: 'some value'}, //note: passes in as form fields
// optionally include array of binary files
binaryFiles: thisFileList
});
来自:Antonio Vázquez [email protected]
发送:2018 年 9 月 11 日星期二上午 11:23
至:axios/axios [email protected]
抄送:DavidRueter [email protected] ; 评论[email protected]
主题:回复:[axios/axios] 无法使用 'Content-Type': 'multipart/form-data' 的 .post 工作 (#318)
从 Safari 发出帖子请求需要 4 个小时,而且还在计数。 仍然没有发生......到底是什么家伙?
这里没有一个解决方案对我有用...... :(
—
您收到此消息是因为您发表了评论。
直接回复此邮件,在 GitHub 上查看https://github.com/axios/axios/issues/318#issuecomment-420371510 ,或将帖子静音https://github.com/notifications/unsubscribe-auth/AFbi6JQBv06LTwL4z3HIAlvXAXDyps1- ks5uZ_9wgaJpZM4Ibm_z 。 https://github.com/notifications/beacon/AFbi6BSPfwPvNaWPFSdvtLKRYXS1m4uKks5uZ_9wgaJpZM4Ibm_z.gif
这也对我有用,谢谢@arvi
twiliosms = async (Codigo) => {
var FormData = require('form-data');
var fs = 需要('fs');
var form = new FormData();
form.append('到', '+524772773737');
form.append('发件人', '+737373737');
form.append('Body', Codigo);
尝试 {
让 axapi = 等待 axios(
{
url: '2010-04-01/Accounts/AC8aa53c907943af79234414bb725c2cd3/Messages.json',
baseURL: 'https://api.twilio.com',
标题:{'内容类型': multipart/form-data; boundary=${form._boundary}
,},
数据:表格,
授权:{
用户名:'AC8aa53c907943af79234414bb725c2cd3',
密码: * ,
},
方法:'发布',
}
)
} 捕捉 (e) {console.error(e)}
}
我在徘徊这个库仍然需要表单数据帖子的自写变通方法....
任何更新?
我在 NodeJS 10.11.0 和 Axios 0.18.0 中有类似的错误(参见 #1892)。 我已经尝试过@arvi的修复,但它不起作用。
对我来说,这有效:
let formData = new FormData(document.querySelector('#form'));
axios.post("/api/xxx", formData).then(console.log).catch(console.error)
这行不通
let formData = new FormData(document.querySelector('#form'));
axios.post("/api/xxx", {data: formData}).then(console.log).catch(console.error)
请注意postdata参数格式应该是(url , FormData)
,而不是(url, {data: FormData})
beforeAll(function (done) {
//parse form fields
var parsefields = function(req,res){
var form = new formidable.IncomingForm();
form.parse(req, function (err, fields, files) {
if (err) res.status(404).json(err)
else res.status(200).json(fields);
});
}
router.route('parsefields').post(parsefields)
//start server
s = express()
s.use('/',router)
s.listen(4000,(err)=>{done(err)})
done()
});
it('should parse and return form fields', function (done) {
const fd = new FormData()
fd.append('key','value')
axios({
method: 'POST',
url: 'http://localhost:4000/parsefields',
data: fd,
headers : fd.getHeaders(),
}).then(function (res) {
expect(res).to.exist
expect(res.body.key).to.equals('value')
}).catch(err => {
expect(err).not.to.exist
})
done()
});
});
我有同样的问题。 收到没有错误的 404。 将强大的用于表单解析器、express 和 axios。
我不知道这是否对任何人有帮助,但我只在 Safari 上看到了这个问题,并通过使用formdata-polyfill修复了它。 Safari 应该原生支持 FormData.append() 但可能实现略有不同?
编辑:我错了:我使用的是从 Blob 创建的 URL。 一旦我开始使用正确的 blob,一切都像魅力一样!
当我可以上传文件时,我对 Blob 有同样的问题。 从 Blob 转换为 File 很简单,但我想知道这是一个错误还是我误解了语法:
`` js
upload () {
let data = new FormData()
data.append('file', this.croppedFile)
data.append('blob', this.croppedBlob, 'blob.jpeg')
axios.post('/api/fp/process/', data, {
headers: {
'Accept':
文本/纯文本`,
},
})
croppedFile is derived from croppedBlob with this simple code:
` return new File([this.cropImg], this.file.name, { type: this.file.type })`
Firefox dev tools show:
------WebKitFormBoundarytmInU7WtcHvmgYbc
内容处置:表单数据; 名称=“斑点”
------WebKitFormBoundarytmInU7WtcHvmgYbc
内容处置:表单数据; 名称=“文件”; 文件名="dscn2950.jpg"
内容类型:图片/jpeg
blob:http :// localhost:8080/9a6446d1-1ca2-4fd3-a6c8-8b36d863c146
------WebKitFormBoundarytmInU7WtcHvmgYbc--
```
根据mozilla formData.append 文档,我似乎可以使用 Blob 对象。
让我陷入困境的是我的服务器没有正确处理文件,使用https://www.npmjs.com/package/multer修复了它
它对我有用! 谢谢!
这里没有什么对我有用,因为我的代码非常好。
真正的问题是我从 Windows 搜索结果中拖动的文件 - Chrome 找不到真实位置,它破坏了整个 FormData 解析。 导航到文件并拖动它解决了这个问题。
大家好,
请帮我。
发布https://www.googleapis.com/upload/drive/v3/files?uploadType=multipart HTTP/1.1
授权:不记名 [YOUR_AUTH_TOKEN]
内容类型:多部分/相关; 边界=foo_bar_baz
内容长度:[NUMBER_OF_BYTES_IN_ENTIRE_REQUEST_BODY]
--foo_bar_baz
内容类型:应用程序/json; 字符集=UTF-8
{
“名称”:“我的对象”
}
--foo_bar_baz
内容类型:图片/jpeg
[JPEG_DATA]
--foo_bar_baz--
axios 不支持多部分/相关请求类型
对我来说,这是(我猜)gulp。 因为我在服务器上收到了缩小文件的错误。 我手动删除了 dist 文件夹中的所有内容,将内容类型保留为未定义,并且一切都按预期工作。
所以你会有类似的东西:
formdata.append("selectPaymentType", $scope.extraFields.selectPaymentType);
formdata.append("pickupMethod", $scope.extraFields.selectPickupType);
让请求 = {
方法:'POST',
url: baseURL + '订单',
数据:表单数据,
标题:{
“内容类型”:未定义,
'x-access-token': $scope.userToken
}
};
$http(请求)
.success(函数(d){})
.error(函数 () { });
PS:这是摘录...我还附加了文件和更多字段...
服务器:
var form = new multiparty.Form({uploadDir : './uploads/orders/'});
form.parse(req, function(err, fields, files) {
//你的代码在这里
})
hii plz我需要帮助:我得到“文件:这个值不应该是空白的。” 当我尝试使用 fetch 获取发布图像时:
handleSubmit = (event) => {
event.preventDefault();
//const { category } = this.state;
console.log(this.state.file)
let formData = new FormData();
formData.append("file",this.state.file);
formData.append("name",this.state.name);
alert('You Added a new Category Named ' + this.state.file);
fetch(`${process.env.REACT_APP_BASE_URL}/category/image`, {
method: 'POST',
body: formData
}).then(res => res.json()).then(err => console.log(err));
}
构造函数(道具){
超级(道具);
this.state = {
name: '',
file: null
,
isLoaded: false,
isEditMode: false,
}
}
```
对于任何人来说,这都对我有用。
如果正在使用输入文件,则必须在获得其他输入字段之前,像中间件一样在 router.post('/') 中使用 MULTER。
检查您的 axios.create,此标头应为“标头:{}”并且不使用数据。像这样:
var instance = axios.create({
标题:{
// 'Content-Type': 'application/x-www-form-urlencoded;charset=UTF-8',
},
// 数据: {},
参数:{}
});
直到今天,这不适用于 nodejs。 request-promise
方法也对我有用。
花了 2 天时间试图让它与 nodejs 中的 axios 一起工作。 花了 30 秒才真正让它在 nodejs 中与 request-promise 一起工作。
我尝试了不同的解决方案,但最后我处理了这个问题,添加了标题:
const FormData = require('form-data')
const axios = require('axios')
const form = new FormData()
form.append('foo', 'bar')
await axios.post('http://myserver', form, { headers: form.getHeaders() })
@Googrosh是的。 是的。 是的。
花了半天时间弄清楚它是否与客户端或服务器配置有关。
最后, headers: form.getHeaders()
成功了。
移动到got
因为它只是 _works_ 与formData
和multipart/form-data
- https://github.com/sindresorhus/got 🙌
关闭,但没有雪茄 Axios 👋
const form = new FormData()
const stream = fs.createReadStream(file.path)
form.append('file', stream, file.name)
try {
await got.post('http://example.com', { body: form })
} catch (error) {
next(error)
}
你可以这样做:
handleSubmit = (e: any) => {
e.preventDefault();
常量数据 = 新 FormData();
data.append('product_csv', this.state.csvfile);
让 accessToken = localStorage.getItem('access_token');
axios
.post('/上传', 数据,
{标题:
{ 'Content-Type': 'multipart/form-data', 授权: accessToken }
})
.then(res => {
console.log('res', res);
});
};
@Googrosh Brilliant, .getHeaders()
也为我工作。 我无法告诉你我为此花了多少时间。 谢谢!
我正在使用本机反应。 我通过使用rn-fetch-blob
结束了这个问题。 太糟糕了 :(
我有同样的问题,它只是不适用于没有任何文件的简单 FormData 并且 .getHeaders() 没有帮助。 移动到“得到”的库,只是工作。 这里也提到了https://github.com/form-data/form-data/issues/458 (我使用的是 Node v12)
2020 ES6 做事方式
拥有 html 中的表单,我在数据中绑定如下:
数据:
form: {
name: 'Joan Cap de porc',
email: '[email protected]',
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')
}
}
@DespertaWeb没有文件时它不起作用。
最有用的评论
@rafaelbiten我刚刚尝试重现该问题,但无济于事。 我使用了以下代码:
数据成功发送到服务器: