Ajax is not sending FormData - javascript

i have a form with enctype of multipart/form-data and i am sending file (image) with FormData and ajax but as i see it is not sending. here is code
$(document).ready(()=>{
$('#form').submit((e)=>{
e.preventDefault();
const formData = new FormData();
const title = $('#title').val();
const news = $('#news').val();
formData.append('title', title);
formData.append('news', news);
formData.append('img', $('#form').find('input[type="file"] [name="thumbnail"]:first')[0].files[0]);
$.ajax({
url: '/admin-panel/add-news',
method: 'POST',
data: formData,
processData: false,
contentType: false,
success: (r)=>{
$('#news-container').html(`<div class="news">${r.news}</div>`);
},
error: (xhr,textStatus,error)=>{
try{
const response = JSON.parse(xhr.responseText);
if(response.message){
$('#error').html(`<p class="err">${response.message}</p>`);
}
}catch(error){
$('#error').html(`<p class="err">${xhr.responseText}</p>`);
}
}
})
})
})
but it gives me error
Uncaught TypeError: Cannot read property 'files'
what is problem?
Thank you!

Check your ajax property - contentType

Related

react axios trying to send both data object and image file but server wont read the file [duplicate]

I am trying to send a file and some json in the same multipart POST request to my REST endpoint. The request is made directly from javascript using axios library as shown in the method below.
doAjaxPost() {
var formData = new FormData();
var file = document.querySelector('#file');
formData.append("file", file.files[0]);
formData.append("document", documentJson);
axios({
method: 'post',
url: 'http://192.168.1.69:8080/api/files',
data: formData,
})
.then(function (response) {
console.log(response);
})
.catch(function (response) {
console.log(response);
});
}
However, the problem is when I inspect the request in chrome developer tools in the network tab, I find no Content-Type field for document, while for file field Content-Type is application/pdf (I'm sending a pdf file).
On the server Content-Type for document is text/plain;charset=us-ascii.
Update:
I managed to make a correct request via Postman, by sending document as a .json file. Though I discovered this only works on Linux/Mac.
To set a content-type you need to pass a file-like object. You can create one using a Blob.
const obj = {
hello: "world"
};
const json = JSON.stringify(obj);
const blob = new Blob([json], {
type: 'application/json'
});
const data = new FormData();
data.append("document", blob);
axios({
method: 'post',
url: '/sample',
data: data,
})
Try this.
doAjaxPost() {
var formData = new FormData();
var file = document.querySelector('#file');
formData.append("file", file.files[0]);
// formData.append("document", documentJson); instead of this, use the line below.
formData.append("document", JSON.stringify(documentJson));
axios({
method: 'post',
url: 'http://192.168.1.69:8080/api/files',
data: formData,
})
.then(function (response) {
console.log(response);
})
.catch(function (response) {
console.log(response);
});
}
You can decode this stringified JSON in the back-end.
you only need to add the right headers to your request
axios({
method: 'post',
url: 'http://192.168.1.69:8080/api/files',
data: formData,
header: {
'Accept': 'application/json',
'Content-Type': 'multipart/form-data',
},
})
You cant set content-type to documentJson, because non-file fields must not have a Content-Type header, see HTML 5 spec 4.10.21.8 multipart form data.
And there`s two way to achieve your goals:
JSON.stringify your data, and decode it in the back-end like this answer below
pass a file-like object and set Content-Type like this answer below

Trying to post data using axios and formData but it's empty

I'm using Vue3 and axios to post a form using FormData, but it's empty, nothing is being passed.
{"formData":{}}
Here's what I am doing:
const formData= new FormData();
formData.set("name", name);
axios.post("postform", formData);
I also tried this:
formData.set("name", "John Doe");
axios.post("postform", formData);
and this:
formData.append("name", "John Doe");
axios.post("postform", formData);
But no success. There's no errors, it's just empty.
I retrieve them in PHP like this:
echo $request->input("name");
So my question is:
How do I post data using FormData?
If you are not sending any file (or your form is not maltipart/form-data) you can use following method to send data through axios:
let formData = {};
formData.name = "John Doe";
axios({
url: "postform",
method: "POST",
data: formData
});
EDIT:
If you are sending any files then in my case following worked for me:
const formData = new FormData();
formData.append("name", "hello world");
axios({
url: 'postform',
method: "POST",
data: formData,
headers: {
'Content-Type': 'multipart/form-data'
}
})
You can convert your FormData Object to simple object and then send that object to server.
const formData = new FormData();
formData.set("key1", "value1");
formData.set("key2", "value2");
let data = {};
// convert the key/value pairs
for(var pair of formData.entries()) {
data[pair[0]] = pair[1];
}
axios.post("postform", data);
You might need to send the header 'Content-Length': formData.getLengthSync(). This call works for me:
const response = await axios.delete(url, {
"data": formData,
"headers": {
"Content-Length": formData.getLengthSync()
}
});

AJAX to fetch, get same funcionality

i want to know how can i get the same funcionality from ajax jquery to fetch javascript
this is my ajax.
$.ajax({
url: url,
type: "POST",
data: data, //FormData
contentType: false,
processData: false,
success: function(result) {
console.log(result);
},
error(e) {
console.log(e.responseJSON.message); //<---this is what i want in my fetch :)"this is my error text"
}
});
and there my fetch
options = {
method: "POST",
body: data // FormData
}
const response = await fetch(url, options);
if(!response.ok){
return response.statusText;//always "internal server error" i need my custom msg for user ;(
}
my backend in laravel
abort(500, "this is my error text");
You have to use response.text() to get the actual response body
options = {
method: "POST",
body: data // FormData
}
const response = await fetch(url, options);
if(!response.ok){
return response.text();
}

sending file and json in POST multipart/form-data request with axios

I am trying to send a file and some json in the same multipart POST request to my REST endpoint. The request is made directly from javascript using axios library as shown in the method below.
doAjaxPost() {
var formData = new FormData();
var file = document.querySelector('#file');
formData.append("file", file.files[0]);
formData.append("document", documentJson);
axios({
method: 'post',
url: 'http://192.168.1.69:8080/api/files',
data: formData,
})
.then(function (response) {
console.log(response);
})
.catch(function (response) {
console.log(response);
});
}
However, the problem is when I inspect the request in chrome developer tools in the network tab, I find no Content-Type field for document, while for file field Content-Type is application/pdf (I'm sending a pdf file).
On the server Content-Type for document is text/plain;charset=us-ascii.
Update:
I managed to make a correct request via Postman, by sending document as a .json file. Though I discovered this only works on Linux/Mac.
To set a content-type you need to pass a file-like object. You can create one using a Blob.
const obj = {
hello: "world"
};
const json = JSON.stringify(obj);
const blob = new Blob([json], {
type: 'application/json'
});
const data = new FormData();
data.append("document", blob);
axios({
method: 'post',
url: '/sample',
data: data,
})
Try this.
doAjaxPost() {
var formData = new FormData();
var file = document.querySelector('#file');
formData.append("file", file.files[0]);
// formData.append("document", documentJson); instead of this, use the line below.
formData.append("document", JSON.stringify(documentJson));
axios({
method: 'post',
url: 'http://192.168.1.69:8080/api/files',
data: formData,
})
.then(function (response) {
console.log(response);
})
.catch(function (response) {
console.log(response);
});
}
You can decode this stringified JSON in the back-end.
you only need to add the right headers to your request
axios({
method: 'post',
url: 'http://192.168.1.69:8080/api/files',
data: formData,
header: {
'Accept': 'application/json',
'Content-Type': 'multipart/form-data',
},
})
You cant set content-type to documentJson, because non-file fields must not have a Content-Type header, see HTML 5 spec 4.10.21.8 multipart form data.
And there`s two way to achieve your goals:
JSON.stringify your data, and decode it in the back-end like this answer below
pass a file-like object and set Content-Type like this answer below

How do I upload a file from Axios to Django?

I'm switching from Jquery AJAX to react-dropzone & Axios, I'd like to upload a file to my Django server, I have no issue posting a blob url of the image on the server but I want to get it under request.FILES but I am getting an empty queryset.
request.FILES : <MultiValueDict: {}> <!--- empty
request.POST : <QueryDict: {}> <!--- able to get a blob url
Here's what my axios configuration looks like :
const temporaryURL = URL.createObjectURL(step3.drop[0]);
var fd = new FormData();
fd.append('image', temporaryURL);
axios({
method: 'post',
url: SITE_DOMAIN_NAME + '/business-card/collect/',
data: fd,
headers: {
"X-CSRFToken": CSRF_TOKEN,
"content-type": "application/x-www-form-urlencoded"
}
}).then(function (response) {
console.log(response)
URL.revokeObjectURL(temporaryURL);
}).catch(function (error) {
console.log(error)
});
I am receiving the file on a classBasedView on POST request.
How can I upload the file? Where am I wrong?
Edit
I also tried "application/form-data", doesn't solve the problem
the problem came from the content-type as it was using "application/form-data" instead of "multipart/form-data".
I am answering in case, someone comes here by searching on google:
let formData = new FormData();
formData.append('myFile', file);
formData.append('otherParam', 'myValue');
axios({
method: 'post',
url: 'myUrl',
data: formData,
headers: {
'content-type': 'multipart/form-data'
}
}).then(function (response) {
// on success
}).catch(function (error) {
// on error
});

Categories