I've try to send a form data with axios but i can't, in chrome dev tools no content appears in the request. Making a same request via postman the API response normally.
js
(newData) => {
const data = new FormData();
data.append('name', 'raphael');
data.append('file', {
uri: newData.image.path,
type: 'image/jpeg',
name: 'teste'
});
return axios.post(`${constants.development.URL_API}/file`, data,
headers: {
'Content-Type': 'multipart/form-data',
},
})`
@corujoraphael Out of curiosity, was this request working earlier?
@corujoraphael I'm not sure that your code runs as-is. The config where you specify your headers should be an object, but it's missing a curly brace:
(newData) => {
const data = new FormData();
data.append('name', 'raphael');
data.append('file', {
uri: newData.image.path,
type: 'image/jpeg',
name: 'teste'
});
return axios.post(
`${constants.development.URL_API}/file`,
data,
{
headers: {
'Content-Type': 'multipart/form-data',
}
},
)
}
Since this issue hasn't received a response and this doesn't look like an Axios bug based on the info we have, I'm closing this issue.
If you need further assistance debugging your code, please post on Stack Overflow, Gitter, or comment again on this issue.
Thanks!
@emilyemorehouse , I met the same problem using React Native FormData
let s = JSON.stringify({ uri: localUri, name: filename, type: type });
let formData = new FormData();
formData.append('ph0t0', s);
axios.post("http://10.0.1.2:8888/uploadphoto", {
method: "POST",
headers: {
'Content-Type': 'multipart/form-data; charset=utf-8; boundary="another cool boundary";'
},
body: formData,
}).then((resp) => {
console.log(resp);
}).catch(err => {
console.log(err);
});
Expect some key:value pairs exist in MultipartForm, Form, or PostForm
2018/02/20 18:25:31.740 [W] [photo.go:411] req.MultipartForm: nil
2018/02/20 18:25:31.740 [W] [photo.go:412] req.Form: map[]
2018/02/20 18:25:31.740 [W] [photo.go:413] req. PostForm: map[]
2018/02/20 18:25:31.740 [W] [photo.go:410] req: &{POST /uploadphoto/dialog/57120e8951c643ab42a8c19f/000000000000000000000001 HTTP/1.1 1 1 map[Content-Type:[application/json;charset=utf-8] User-Agent:[okhttp/3.6.0] Accept:[application/json, text/plain, /] Content-Length:[419] Connection:[Keep-Alive] Accept-Encoding:[gzip] Cookie:[lang=zh-TW; PVsessionID=db9a21d63b2d0ea47b68fa8755bd87e2]] 0xc420e3cb80
2018/02/20 18:25:31.740 [E] [photo.go:425] [UploadPhotos] err: request Content-Type isn't multipart/form-data
Version info
axios: 0.16.2
expo: 25.0.0
react: 16.2.0
react-native: 0.52.0
This bug still happens with latest axios, why was this closed?
If someone can provide a reproducible example, I'm happy to open this back up.
@Ernie6711 it looks like you have an error in your code -- I don't think you should stringify the file data before appending it to your form data. Also, the arguments for axios.post are axios.post(url[, data[, config]])
Here's an example based on your code:
const file ={ uri: localUri, name: filename, type: type};
const formData = new FormData();
formData.append('file', s);
const config = {
headers: {
'Content-Type': 'multipart/form-data; charset=utf-8; boundary="another cool boundary";'
}
};
axios.post("http://10.0.1.2:8888/uploadphoto", formData, config).then((resp) => {
console.log(resp);
}).catch(err => {
console.log(err);
});
@emilyemorehouse please check wireshark traces. The data is uploaded but it does NOT use proper form-data encoding. The above example can reproduce the problem. Again - the request is being sent successfully but is it badly encoded.
POST /myserver HTTP/1.1
Content-Type: multipart/form-data
_parts=USERX%2Cusername&_parts=FILE1%2C%5Bobject%20Object%5D
I have a local client and server example for file uploads, albeit outside of the React Native environment, that works and is properly encoded. The example above isn't really reproducible since it relies on variables and a server that I don't have access to.
My guess is that if there's something incorrect with the upload, it's because the data appended to the form data object is not valid.
@emilyemorehouse File uploads work perfectly in a browser environment, they only fail on react native. As you mentioned yourself - your tests were outside of react native environment, I would start there :)
Try a simple file upload in react native and simply check the wireshark traces, you don't even need a working server...
I got the same, Axios does not on react native
@duongtranpyco I've removed axios from my project, I wrote my own simple class instead, enjoy!
P.S. If you mainly sending JSON, modify the code. In my case, the server usually expects a form.
const request = async ({url, method = 'GET', params, body, responseType = 'json', headers = {}})=>{
const escape = (data, encode = encodeURIComponent)=>Object.keys(data||{}).reduce((pairs, key)=>{
for (let value of [].concat(data[key]))
pairs.push([`${key}`, `${value}`]);
return pairs;
}, []).map(pair=>pair.map(encode).join('=')).join('&');
if (Object.keys(params||{}).length)
url += '?'+escape(params);
if (method=='POST' && typeof body=='object')
{
if (body instanceof FormData)
headers['Content-Type'] = 'multipart/form-data';
else
{
body = escape(body);
headers['Content-Type'] = 'application/x-www-form-urlencoded';
}
}
let {statusCode, request: req} = await new Promise((resolve, reject)=>{
let xhr = new XMLHttpRequest();
xhr.open(method, url, true);
xhr.withCredentials = true;
xhr.responseType = {json: 'text'}[responseType]||responseType;
xhr.onload = ()=>resolve({statusCode: xhr.status, request: xhr});
xhr.onerror = ()=>reject(new TypeError('Network request failed'));
xhr.ontimeout = ()=>reject(new TypeError('Network request timed out'));
for (let key in headers)
xhr.setRequestHeader(key, headers[key]);
xhr.send(body||null);
});
if (statusCode<200 || statusCode>=400)
throw new Error(`network request failed with ${statusCode}: ${url}`);
switch(responseType)
{
case 'json':
return JSON.parse(req.responseText);
case 'text':
return req.responseText;
case 'request':
return req;
}
return req.response;
};
request.get = (url, opt = {})=>request({...opt, url, body: null});
request.post = (url, ...args)=>request({...args[1]||{}, url, method: 'POST', body: args[0]});
Hi, I am facing the same problem. Has anybody found a solution?
Second @giladno. Since I'm going forward on other parts, I use a workaround instead: write a specific function with fetch() when uploading images.
Tried before and neither stringifying the data or arguments affect the result. The server received the call but no data sent.
@Ernie6711 apparently the headers are corrupted and that is why the server is unable to accept the form data. I implemented the workaround with fetch() and it worked with no problems.
I did have the some problem in react-native.
The problem are not the Headers.
In web we can have for example:
let formData = new FormData()
formData.append('key', true // bool value)
but in react native the value for key must be string.
formData.append('key', 'true')
I have the same issue on react native when I post to a url, as @giladno mentions, you should test in react native and you could verify the error that people report @emilyemorehouse. I report an error 14 days ago https://github.com/axios/axios/issues/1618, but nobody has responded, please describe in the readme of your library that you do not have support for axios on react native, so that many developers do not waste time..!
Y'all, I appreciate the direction but "just test a file upload in React Native" isn't that easy. I don't often work in React Native and it would take a decent amount of time to spin up a project with file uploads to test with.
I do have a simple POST with form data that works in React Native:
const formData = new FormData();
formData.append("data", true);
const config = {
headers: {
"Content-Type": "multipart/form-data; charset=utf-8;"
}
};
axios.post(URL, formData, config).then(
response => {
console.log({ response });
},
error => {
console.log({ error });
}
);
true
gets stringified when sent to the server, which is interesting.
That said, if anyone can provide an example that I can easily spin up, I'm happy to look into it more.
@corujoraphael how did you solved this?
I added a type inside the image object like "Image.type='image/png"
just before append and also changed the content type to "Content-Type":"multipart/form-data"
:
image.type='image/png'
formData.append("resource", image);
return axios
.post('yourBAckendUrl', formData, {
headers: {
Authorization: "yourTokenHere",
"Content-Type": "multipart/form-data"
}
})
Hope this help someone.
I was unable to get this to work as well, I'm trying to PUT multipart/form-data to S3 (video). Using the type option didn't help. The multipart/form-data header doesn't seem to be in the PUT request:
const data = new FormData();
data.append('video', {
uri: 'file:///<path_to_video_on_iphone.mov',
type: 'video/quicktime',
name: 'video.mov',
});
response = yield call(() => {
return api.put(url, data, {
headers: {
'Content-Type': 'multipart/form-data',
},
transformRequest: [
(data, headers) => {
delete headers.common.Authorization;
return data;
}
]
});
});
For this case use fetch :D
var data = new FormData();
data.append('my_photo', {
uri: filePath, // your file path string
name: 'my_photo.jpg',
type: 'image/jpg'
}
fetch(path, {
headers: {
'Accept': 'application/json',
'Content-Type': 'multipart/form-data'
},
method: 'POST',
body: data
});
in axios version 0.18.0
having same issue.
axios removes internally the header Content-Type
if there is no body on the post, put
etc for some reason when creating FormData
the body remains empty..
this is my code:
const sendFormData = images => {
// images is an array of base64 images (strings)
const formData = new FormData();
images.forEach((img, i) => {
formData.append('file', img);
formData.append('name', `${type}-${i + 1}`);
});
config.headers = {
.'Content-Type': 'multipart/form-data'
};
return axios.post(`http://someurl.com/api/upload-images`, formData, config)
.then(response => {
// handle success
})
.catch(err => {
// handle err
});
}
React Native version 0.55.3
this example code is not working. request body is empty and the Content-Type
header is removed
i have same issues and my body when i check in debug is string
and here my code
const formData = new FormData();
formData.append('photo', {
uri: response.uri.replace('file://', ''),
mineType: 'image/jpeg',
fileType: 'image/jpg',
type: 'image/jpg',
name: 'test.jpg'
});
console.log('form data', formData);
Axios({
method: 'post',
url: 'https://dev-host.luxstay.net/api/rooms/10740/photos',
data: formData,
headers: {
Authorization: token,
'Content-Type': 'multipart/form-data'
}
});
Update : An error occurred because the app was in debug mode. When i turn off debug mode , it worked
axios has a code in its xhr adapter
if (utils.isFormData(requestData)) {
delete requestHeaders['Content-Type']; // Let the browser set it
}
i guess in react-native it deletes the content-type header if you are sending multipart form data even if you set it in the code .
But I am not sure if commenting the line out would resolve your issue in react-native.
in axios version
0.18.0
having same issue.
axios removes internally the headerContent-Type
if there is no body on thepost, put
etc for some reason when creatingFormData
the body remains empty..
this is my code:const sendFormData = images => { // images is an array of base64 images (strings) const formData = new FormData(); images.forEach((img, i) => { formData.append('file', img); formData.append('name', `${type}-${i + 1}`); }); config.headers = { .'Content-Type': 'multipart/form-data' }; return axios.post(`http://someurl.com/api/upload-images`, formData, config) .then(response => { // handle success }) .catch(err => { // handle err }); }
React Native version
0.55.3
this example code is not working. request body is empty and theContent-Type
header is removed
So what should it look like? I have object object as well.
@tkserver it's look like when you have a object and then you toString() it.
const a = {
name: 'dasdasd'
}
console.log(a.toString());
@tkserver it's look like when you have a object and then you toString() it.
const a = { name: 'dasdasd' } console.log(a.toString());
Perhaps I wasn't clear. Should the Request Payload show [object Object] when viewing the headers?
@tkserver if your debugger has network inspect enabled, it will override the react-native's FormData and will result in passing empty FormData object which will look like [Object object] in network inspect.
Try making request with turning off network inspect, hope this helps.
Thanks Aman725, minhphung210 and all. When I use the code on a real device the upload works properly. It would seem this is related to the iOS simulator.
I had this problem, but it's fixed now.
The reason for it was that I was debugging network requests. I had this line of code in my app's entry point:
GLOBAL.XMLHttpRequest = GLOBAL.originalXMLHttpRequest || GLOBAL.XMLHttpRequest;
I commented it and it works now.
// IMPORTANT: this will cause FormData requests to fail.
// GLOBAL.XMLHttpRequest = GLOBAL.originalXMLHttpRequest || GLOBAL.XMLHttpRequest;
I just found this: https://stackoverflow.com/a/47630754/387912, does it help?
XMLHttpRequest
Can you tell me how did you build the request so it uploads properly as multiparty? I keep getting a network error:
Error: Network Error
at createError (blob:http://localhost:8081/0754d453-361d-48d1-aaa5-9ff1ad808293:168963:17)
at XMLHttpRequest.handleError (blob:http://localhost:8081/0754d453-361d-48d1-aaa5-9ff1ad808293:168871:16)
at XMLHttpRequest.dispatchEvent (blob:http://localhost:8081/0754d453-361d-48d1-aaa5-9ff1ad808293:28708:27)
at XMLHttpRequest.setReadyState (blob:http://localhost:8081/0754d453-361d-48d1-aaa5-9ff1ad808293:28461:20)
at XMLHttpRequest.__didCompleteResponse (blob:http://localhost:8081/0754d453-361d-48d1-aaa5-9ff1ad808293:28288:16)
at blob:http://localhost:8081/0754d453-361d-48d1-aaa5-9ff1ad808293:28398:47
at RCTDeviceEventEmitter.emit (blob:http://localhost:8081/0754d453-361d-48d1-aaa5-9ff1ad808293:3291:37)
at MessageQueue.__callFunction (blob:http://localhost:8081/0754d453-361d-48d1-aaa5-9ff1ad808293:2588:44)
at blob:http://localhost:8081/0754d453-361d-48d1-aaa5-9ff1ad808293:2345:17
at MessageQueue.__guard (blob:http://localhost:8081/0754d453-361d-48d1-aaa5-9ff1ad808293:2542:13)
UPDATE: manage to make it work now. Currently using:
formData.append('picture', {
uri: data.uri,
name: fname,
type: 'image/' + ext
});
If people are still experiencing this issue, and you have
GLOBAL.XMLHttpRequest = GLOBAL.originalXMLHttpRequest || GLOBAL.XMLHttpRequest;
snippet to debug network requests, try adding
GLOBAL.FormData = GLOBAL.originalFormData || GLOBAL.FormData
it worked for me.
I added a type inside the image object like
"Image.type='image/png"
just before append and also changed the content type to"Content-Type":"multipart/form-data"
:image.type='image/png' formData.append("resource", image); return axios .post('yourBAckendUrl', formData, { headers: { Authorization: "yourTokenHere", "Content-Type": "multipart/form-data" } })
Hope this help someone.
Thanks for your help! I was able to upload my picture with the iOS Simunator but not with the android one.
After I did set the image type to 'image/jpeg' I stopped having the Network Error.
const formData = new FormData();
formData.append('file', {
uri: pictureUri,
type: 'image/jpeg',
name: 'profile-picture'
})
I added a type inside the image object like
"Image.type='image/png"
just before append and also changed the content type to"Content-Type":"multipart/form-data"
:image.type='image/png' formData.append("resource", image); return axios .post('yourBAckendUrl', formData, { headers: { Authorization: "yourTokenHere", "Content-Type": "multipart/form-data" } })
Hope this help someone.
Thanks for your help! I was able to upload my picture with the iOS Simunator but not with the android one.
After I did set the image type to 'image/jpeg' I stopped having the Network Error.
const formData = new FormData(); formData.append('file', { uri: pictureUri, type: 'image/jpeg', name: 'profile-picture' })
For anyone that this may be of help, if you don't know the type of the content that will be sent over, use the multipart/form-data
. It sounds obvious reading this now, but it took me a good hour to get any media working.
data.append("image", {
name: "some_name", // also, won't work without this. A name is required
height: image.height,
width: image.width,
type: "multipart/form-data", // <-- this part here
uri:
Platform.OS === "android" ? image.uri : image.uri.replace("file:/", "")
});
Hi, I am trying to file Axios upload in Vue.Js. Can anyone review and explain the issue?
In Html
<input type="file" id="file" ref="file" multiple @change="assignFiles"/>
In Js
` assignFiles(e){
let uploadedFiles = this.$refs.file.files;
for( var i = 0; i < uploadedFiles.length; i++ ) {
this.form.AttachmentDocs.push(uploadedFiles[i]);
}
console.log(this.form.AttachmentDocs);
},`
So, while trigger the post, am appending form datas.
`proceedSave(e) {
e.preventDefault();
this.$v.$touch();
if(this.$v.$invalid) {
return;
}
this.showLoading(this.loaderId,true);
this.postDatas.append('form',JSON.stringify(this.form));
for( var i = 0; i < this.form.AttachmentDocs.length; i++ ){
let attachment = this.form.AttachmentDocs[i];
this.postDatas.append('files['+i+']',attachment,attachment.name);
}
}`
So In the post, I checked console window header, there its showing
files[0]: (binary)
files[1]: (binary)
files[2]: (binary)
files[3]: (binary)
In My server side i cnt to get the files.
Might have something to do with
this.postDatas.append('files['+i+']',attachment,attachment.name);
Try files['+' + i + '+']
I have the same issue with fetch api. req.body was empty in node js. Using 'express-formidable' solved the issue. https://www.npmjs.com/package/express-formidable
Might have something to do with
this.postDatas.append('files['+i+']',attachment,attachment.name);
Try
files['+' + i + '+']
Sry + indicates the concatination, wat is the use of string '+' . It result will be files[+0+]
I have the same issue with fetch api. req.body was empty in node js. Using 'express-formidable' solved the issue. https://www.npmjs.com/package/express-formidable
Did you include app.use(express.json({ extended: false }));
?
Might have something to do with
this.postDatas.append('files['+i+']',attachment,attachment.name);
Try
files['+' + i + '+']
Sry + indicates the concatination, wat is the use of string '+' . It result will be files[+0+]
Your current code will always result in files[+i+]
in your for loop. It will never be files[+0+], files[+1+], files[+2+], etc
.
Also, files[+0+]
will never exist. Not sure what you are trying to do. You need files[0], files[1], files[2]...
? If you're trying to build an object, then you can have files['+0+']
, but, again, I'm not sure what you're trying to accomplish.
I have the same issue with fetch api. req.body was empty in node js. Using 'express-formidable' solved the issue. https://www.npmjs.com/package/express-formidable
Did you include
app.use(express.json({ extended: false }));
?
No. However, in formidable I have one issue. Uploaded picture is going to requiest fields. Nothing in request files. Not sure why this is happening.
@duongtranpyco I've removed axios from my project, I wrote my own simple class instead, enjoy!
P.S. If you mainly sending JSON, modify the code. In my case, the server usually expects a form.
const request = async ({url, method = 'GET', params, body, responseType = 'json', headers = {}})=>{ const escape = (data, encode = encodeURIComponent)=>Object.keys(data||{}).reduce((pairs, key)=>{ for (let value of [].concat(data[key])) pairs.push([`${key}`, `${value}`]); return pairs; }, []).map(pair=>pair.map(encode).join('=')).join('&'); if (Object.keys(params||{}).length) url += '?'+escape(params); if (method=='POST' && typeof body=='object') { if (body instanceof FormData) headers['Content-Type'] = 'multipart/form-data'; else { body = escape(body); headers['Content-Type'] = 'application/x-www-form-urlencoded'; } } let {statusCode, request: req} = await new Promise((resolve, reject)=>{ let xhr = new XMLHttpRequest(); xhr.open(method, url, true); xhr.withCredentials = true; xhr.responseType = {json: 'text'}[responseType]||responseType; xhr.onload = ()=>resolve({statusCode: xhr.status, request: xhr}); xhr.onerror = ()=>reject(new TypeError('Network request failed')); xhr.ontimeout = ()=>reject(new TypeError('Network request timed out')); for (let key in headers) xhr.setRequestHeader(key, headers[key]); xhr.send(body||null); }); if (statusCode<200 || statusCode>=400) throw new Error(`network request failed with ${statusCode}: ${url}`); switch(responseType) { case 'json': return JSON.parse(req.responseText); case 'text': return req.responseText; case 'request': return req; } return req.response; }; request.get = (url, opt = {})=>request({...opt, url, body: null}); request.post = (url, ...args)=>request({...args[1]||{}, url, method: 'POST', body: args[0]});
I am using this code in my project. I am trying to understand this code. One question, is this line necessary,
for (let value of [].concat(data[key]))? It can be written simply,
pairs.push([${key}
, ${data[key]}
]);
If people are still experiencing this issue, and you have
GLOBAL.XMLHttpRequest = GLOBAL.originalXMLHttpRequest || GLOBAL.XMLHttpRequest;
snippet to debug network requests, try adding
GLOBAL.FormData = GLOBAL.originalFormData || GLOBAL.FormData
it worked for me.
Where it is?
I also had the problem. It is caused by the file path in android.
const path = utils.isAndroid() ? file://${filePath}
: filePath;
And it works ok with implementing as the following
const formData = new FormData();
const path = utils.isAndroid() ? `file://${filePath}` : filePath;
formData.append('Voice', {
uri: path,
name: 'test',
type: 'audio/wav',
});
formData.append('Content-Type', 'audio/wav');
const headers = {
'Content-Type': 'multipart/form-data',
};
return this._sendRequest(url, 'POST', formData, headers);
data.append('file', {
uri: newData.image.path,
type: 'image/jpeg',
name: 'teste'
Use name like : name:'teste.jpeg'
and it will work. you need to give format to file otherwise it will not work.
I fixed it by having name:'example.jpeg'
After several days trying to upload video with axios, I just give up. RNFetchBlob is better option for uploading files from especially Android. This section is easy to implement
Most helpful comment
This bug still happens with latest axios, why was this closed?