I am learning NextJS/Django. I am trying to send some FormData to my Django back end. It contains some strings and an image file. But, I am getting the following error:
django.http.multipartparser.MultiPartParserError: Invalid boundary in multipart: None
Form:
<form
className={styles.formContainer}
method="post"
encType="multipart/form-data"
onSubmit={handleSubmit}
>
<div className="form-group">
<label htmlFor="email" className={styles.text}>
Email address
</label>
<input
type="email"
className="form-control"
id="email"
aria-describedby="emailHelp"
placeholder="Change email here"
onChange={(e) => setEmail(e.target.value)}
/>
</div>
<div className="form-group">
<label htmlFor="image" className={styles.text}>
Image
</label>
<input
type="file"
className="form-control"
id="image"
accept="image/*"
onChange={(e) => setImageLink(e.target.files[0])}
/>
</div>
<div className="form-group">
<label htmlFor="description" className={styles.text}>
Description
</label>
<textarea
className="form-control"
id="description"
rows="5"
onChange={(e) => setDescription(e.target.value)}
></textarea>
</div>
<button
type="submit"
className="btn btn-primary"
style={{ marginTop: "7px" }}
>
Submit
</button>
</form>
Submit Button:
function handleSubmit(e) {
e.preventDefault();
let data = new FormData();
data.append("userID", loggedInID);
data.append("email", email);
data.append("description", description);
data.append("image", imageLink);
fetch("http://127.0.0.1:8000/user/edit_profile/", {
method: "POST",
headers: {
"Content-Type": "multipart/form-data",
"X-CSRFToken": csrfToken,
},
credentials: "include",
body: data,
}).then((response) => response);
}
Django View:
#parser_classes([FormParser, MultiPartParser])
#csrf_exempt
def editProfileView(request):
print(request.data)
return JsonResponse({})
The Django view is currently unfinished, as I cannot read the data in the sent FormData. Any help is appreciated.
Related
I am trying to send data to my contact form api through react but I am getting this problem
I tried to get input as a value to post through api when clicked on submit button but it is not working
error = the api should call like this https://edu.orgiance.com/api/contactus?secret=xxxxx-ac40-46a0-9c81-d48a1322f4bb&fname=test&email=test#test.com&mobile=8463274946&message=test
but it is calling like this
http://localhost:3000/?name=dfdfsd&email=dsffdsf%40gmail.com&phone=937285294&website=sxascsac&message=dscdscsfgcd#
My Code
import React from 'react';
const ContactForm = (props) => {
const { submitBtnClass } = props;
function handleClick() {
// Send data to the backend via POST
fetch('https://edu.orgiance.com/api/contactus?secret=f1794e34-ac40-46a0-9c81-d48a1322f4bb&fname=test&email=test#test.com&mobile=8463274946&message=', { // Enter your IP address here
method: 'POST',
mode: 'cors',
body: JSON.stringify(jsonData) // body data type must match "Content-Type" header
})
}
var jsonData = {
"contact": [
{
"fname": props.fname,
"email": props.email,
"mobile": props.phone,
"message": props.message
}
]
}
return (
<form id="contact-form" action="#">
<div className="row">
<div className="col-md-6 mb-30">
<input className="from-control" type="text" id="name" name="name" placeholder="Name" value={props.fname} required />
</div>
<div className="col-md-6 mb-30">
<input className="from-control" type="text" id="email" name="email" placeholder="E-Mail" value={props.email} required />
</div>
<div className="col-md-6 mb-30">
<input className="from-control" type="text" id="phone" name="phone" placeholder="Phone Number" value={props.phone} required />
</div>
<div className="col-md-6 mb-30">
<input className="from-control" type="text" id="website" name="website" placeholder="Your Website" required />
</div>
<div className="col-12 mb-30">
<textarea className="from-control" id="message" name="message" placeholder="Your message Here" value={props.message}></textarea>
</div>
</div>
<div className="btn-part" >
<button onClick={handleClick} className={submitBtnClass ? submitBtnClass : 'readon learn-more submit'} type="submit">Submit Now </button>
</div>
</form>
);
}
export default ContactForm;
You're code has a few issues:
jsonData never gets updated, because any update to a state or prop will rerender your function and therefore reinitialize jsonData
Any value that is set on an input or textarea requires an onChange handler. Without it, you can't even type anything into the respective element. See https://reactjs.org/docs/forms.html#controlled-components for more information.
To make your code work, change jsonData into a state that get's initialized with the props data. To make an easier example, I will use contact as state and got rid of the array:
import React, { useState } from "react";
const ContactForm = (props) => {
const { submitBtnClass, ...other } = props;
const [contact, setContact] = useState({
fname: "",
email: "",
mobile: "",
message: "",
...other
});
function handleClick() {
// Send data to the backend via POST
fetch(
"https://edu.orgiance.com/api/contactus?secret=f1794e34-ac40-46a0-9c81-d48a1322f4bb&fname=test&email=test#test.com&mobile=8463274946&message=",
{
// Enter your IP address here
method: "POST",
mode: "cors",
body: JSON.stringify(contact) // body data type must match "Content-Type" header
}
);
}
function setContactData(e) {
const name = e.currentTarget.name;
const value = e.currentTarget.value;
setContact((prev) => {
return {
...prev,
[name]: value
};
});
}
return (
<form id="contact-form" action="#">
<div className="row">
<div className="col-md-6 mb-30">
<input
className="from-control"
type="text"
id="name"
name="fname"
placeholder="Name"
value={contact.fname}
onChange={setContactData}
required
/>
</div>
<div className="col-md-6 mb-30">
<input
className="from-control"
type="text"
id="email"
name="email"
placeholder="E-Mail"
value={contact.email}
onChange={setContactData}
required
/>
</div>
<div className="col-md-6 mb-30">
<input
className="from-control"
type="text"
id="phone"
name="phone"
placeholder="Phone Number"
value={contact.phone}
onChange={setContactData}
required
/>
</div>
<div className="col-md-6 mb-30">
<input
className="from-control"
type="text"
id="website"
name="website"
placeholder="Your Website"
value={contact.website}
onChange={setContactData}
required
/>
</div>
<div className="col-12 mb-30">
<textarea
className="from-control"
id="message"
name="message"
placeholder="Your message Here"
value={contact.message}
onChange={setContactData}
></textarea>
</div>
</div>
{JSON.stringify(contact)}
<div className="btn-part">
<button
onClick={handleClick}
className={
submitBtnClass ? submitBtnClass : "readon learn-more submit"
}
type="submit"
>
Submit Now{" "}
</button>
</div>
</form>
);
};
const App = () => {
return <ContactForm message={"test"} />;
};
export default App;
I am using Bootstrap/jquery for client side. On server side I am using node.js and express
The form is as follows:
<form id="signupform" action="">
<h2>Sign Up</h2>
<p>Please fill in this form to create an account!</p>
<hr>
<div class="form-group">
<input type="text" class="form-control" id="username" placeholder="Username" required="required">
</div>
<div class="form-group">
<input type="email" class="form-control" id="email" placeholder="Email" required="required">
</div>
<div class="form-group">
<input type="number" class="form-control" id="contact" placeholder="Contact" required="required">
</div>
<div class="form-group">
<input type="password" class="form-control" id="password" placeholder="Password" required="required">
</div>
<div class="custom-file">
<label class="custom-file-label" for="cover">Profile Picture</label>
<input type="file" class="custom-file-input" id="cover">
</div>
<div class="form-group">
<button type="submit" class="btn btn-primary btn-lg" id="sign-up">Sign Up</button>
</div>
</form>
My jquery is as follows:
$(document).ready(function(){
$("#sign-up").click(function(event){
event.preventDefault();
var formData = new FormData();
formData.append("username",$("#username").val())
formData.append("email",$("#email").val())
formData.append("contact",$("#contact").val())
formData.append("password",$("#password").val())
formData.append("cover",$("#cover")[0].files)
$.ajax({
url: "http://localhost:3000/users/",
type: 'POST',
data: formData,
success: function (data) {
alert(data)
},
cache: false,
contentType: false,
processData: false
});
});
});
On server side, when I view the incoming request I see this:
body: {
username: 'Sree',
email: 'example#gmail.com',
contact: '1',
password: '1',
cover: '[object FileList]'
},
On the server side I am using express-fileupload, but the image is being sent in the body instead of req.files. How to send formData's file to req.files instead of body?
You should be passing a File object to append(), to access the file object use the prop method to get access to the FileList and take the item at the first index
formData.append("cover", $("#cover").prop('files')[0])
I keep getting a 500 error server when I try to submit form data to my API /users/signup. I verified that the API works using Postman so I think the way I am doing my fetch post is wrong. What is the best practice here?
JS
document.getElementById("create_user").addEventListener("click", (e) => {
e.preventDefault();
const signup = {
username: document.querySelector("#create_username").value.toString(),
email: document.querySelector("#create_email").value.toString(),
password: document.querySelector("#create_password").value.toString()
}
const data = new FormData();
data.append("json", JSON.stringify(signup));
fetch('/users/signup', {
method: 'POST',
body: data
})
.then((response) => response.json())
.catch((error) => {
console.error('Error:', error);
});
});
HTML
<form class="hide" id="sign_up_form">
<div class="form-row">
<h3>Sign up</h3>
</div>
<div class="form-row">
<div class="form-group col">
<label for="create_username">Username</label>
<input id="create_username" name="username" type="text" class="form-control" placeholder="Username">
</div>
</div>
<div class="form-row">
<div class="form-group col">
<label for="create_email">Email</label>
<input id="create_email" name="email" type="email" class="form-control" placeholder="Email">
</div>
</div>
<div class="form-row">
<div class="form-group col">
<label for="create_password">Password</label>
<input id="create_password" name="password" type="password" class="form-control" placeholder="Password">
<small id="passwordHelp" class="text-muted">
Must be at least 8 characters long
</small>
</div>
</div>
<div class="form-row flex-end">
<div class="form-group col-auto">
<button id="create_user" type="submit" class="btn btn-warning mb-2">Sign up</button>
</div>
</div>
<div class="form-row">
<span class="mr-2">Already have an account?</span>Login
</div>
</form>
You don't need to create a form object, you can directly send the json data to your backend.
Add yous json data in the body and the 'Content-Type': 'application/json' header in the request.
The value property of the querySelector method will always return string, you don't need to call toString method on it.
Try this.
document.getElementById("create_user").addEventListener("click", (e) => {
e.preventDefault();
const signup = {
username: document.querySelector("#create_username").value,
email: document.querySelector("#create_email").value,
password: document.querySelector("#create_password").value
}
fetch('/users/signup', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify(signup)
})
.then((response) => response.json())
.then(data => console.log(data))
.catch((error) => {
console.error('Error:', error);
});
});
Here's my form code
html += `</div>
<div class="card-footer">
<form id="messageSendDashboardGroup" enctype="multipart/form-data">
<div class="image-upload">
<div class="input-group" >
<input type="hidden" name="id" value="${id}" />
<input type="hidden" name="name" value="${name}" />
<input type="hidden" name="prefix" value="${prefix}" />
<input type="text" name="message" class="form-control">
<span class="input-group-append">
<label for="file-input" style="margin-bottom: 0px;">
<span class="input-group-text" style="height: 100%;"><i class="fa
fa-upload"></i></span>
<span><input id="file-input" type="file" name="image"></span>
</label>
<button type="submit" class="btn btn-danger">Send</button>
</span>
</div>
</div>
</form>
</div>`;
$('.empChatMessagesShowHere').append(html);
It will generate the form
$('#messageSendDashboardGroup').on('submit', function (e)
{
e.preventDefault();
var formData = new FormData(this);
$.ajax({
url: base_url + 'dashboard/image_api',
data: formData,
type: 'post',
cache: false,
contentType: false,
processData: false,
success: function (data)
{
console.log(data);
}
});
In my controller when i debug $_FILES its returning emtpy array
function image_api()
{
debug($_FILES);
}
Array
(
[image] => Array
(
[name] =>
[type] =>
[tmp_name] =>
[error] => 4
[size] => 0
)
)
I have tried many things but still i am getting an empty $_FILES array kindly help me please, i am using this form to upload image.
I Just change my code to this and it works
html += `</div>
<div class="card-footer">
<form id="messageSendDashboardGroup" enctype="multipart/form-data">
<div class="image-upload">
<div class="input-group" >
<input type="hidden" name="id" value="${id}" />
<input type="hidden" name="name" value="${name}" />
<input type="hidden" name="prefix" value="${prefix}" />
<input type="text" name="message" class="form-control">
<button type="submit" class="btn btn-danger">Send</button>
<input type="file" name="image" class="mt-2" />
</div>
</div>
</form>
</div>`;
$('.empChatMessagesShowHere').append(html);
Before i am using input-prepend button for file upload now i am using default file upload button and it works.
here email should be showing null
That's why i am getting the error 412
and my code is look like
function Submit() {
var objectData =
{
"emailId": $("#emailId").val(),
"password": $("#password").val()
};
var objectDataString = JSON.stringify(objectData);
console.log(objectDataString);
localStorage.setItem("email",$("#emailId").val());
$.ajax({
type: "POST",
url: "http://localhost:8080/feasthunt/common/changePassword",
contentType: "application/json; charset=utf-8",
data: objectDataString,
dataType: "json",
success: function (data,status,xhr) {
console.log(objectDataString);
alert('success');
},
error: function () {
alert('error');
}
});
}
<div class="container">
<div class="col-md-4 col-md-offset-4">
<form role="form" id="form">
<div class="heading"><h3 class="text-center">Change Password</h3></div>
<div class="form-group" class="hidden" style="display:none">
<label for="emailId">EmailId</label>
<input type="emailId" class="form-control" id="emailId" placeholder="emailId" required />
</div>
<div class="form-group">
<label for="pwd">Old Password:</label>
<input type="password" class="form-control" id="password" placeholder="Old Password" required />
</div>
<div class="form-group">
<label for="pwd">New Password:</label>
<input type="password" class="form-control" id="password1" placeholder="New Password" required />
</div>
<div class="form-group">
<label for="pwd">Retype New Password:</label>
<input type="password" class="form-control" id="password2" placeholder="Retype New Password" required />
</div>
<input class="text-center" type="submit" class="btn btn-default" value="SAVE CHANGES" onclick="Submit()">
</form>
</div>
</div>
and above is HTML code
so how can i get email?
here the only problem is email
tell me one thing it is possible to get the email
so any one can answer this question
You don't need to stringify your object, you can just send objectData. If you really need the parameters as JSON, you will have to assign a variable name for it, like {data:JSON.stringify(objectData)}.
You're sending the old password, not the new one.
And, are your running the script at http://localhost:8080? It may not have access to http://localhost:8080/feasthunt/common/changePassword from file:// or from other domain.
Check http://localhost:8080/feasthunt/common/changePassword for errors. You may find useful the Network tab of the webkit's (Chrome/Opera/etc.) Inspector.