I am trying to upload an image via AJAX with a Django view. Here is my HTML form.
<form class="BackgroundImageUplaoder" action="/uplaod" id="form2">{% csrf_token %}
<input type="file" accept="/image*" name="image" multiple="false" />
<button type="submit">Uplaod</button>
While the corresponding ajax is:-
$(document).ready(function(){
$('#form2').submit(function(){
var csrftoken = $("[name=csrfmiddlewaretoken]").val();
var formdata={
'image':$('input[name=image]').val(),
};
console.log("Formvalue is taken");
console.log(formdata.image);
$.ajax({
type:'POST',
url:'/Upload/Background/',
data:formdata,
dataType:'json',
encode:true,
headers:{
"X-CSRFToken": csrftoken
},
processData:false,
contentType:false,
})
.done(function(data){
console.log(data);
if(!data.success){//we will handle error
if (data.password){
console.log(data.password);
$('#password_error').text(data.password);
}
return false;
}
else{
window.location='/';
}
});
event.preventDefault();
});
});
and django view is:-
def uploadbackground(request):
if request.method=="POST":
form=BackgroundImageUplaod(request.POST,request.FILES)
if form.is_valid():
instance=form.save(commit=False)
myobject=HomeScreen.objects.get(profile__user=request.user)
if myobject:
myobject.image=instance
myobject.save()
return JsonResponse({'success':True})
else:
sample=HomeScreen(profile__user=request.user,image=instance)
sample.save()
return JsonResponse({'success':True})
else:
form=BackgroundImageUplaod()
return JsonResponse({'image':'An error is encountered while uplaoding','errors': [(k, v[0]) for k, v in form.errors.items()]})
The console is showing following error
According to my view, The form is not validating.After validating my forming. I am checking that whether the instance correponding to current logged in user exist or not.If yes i am updating that instance otherwise creating new object
Your issue is that you cannot send an image via an AJAX JSON POST, which only accepts strings and integers. You need to use formData.
https://webkul.com/blog/send-images-through-ajax/
Having some difficulty understanding how to access type="file" input on the server side. Below is the code I'm using. I use AJAX because I want my web app to not require refreshing, and am using a slightly roundabout way of submitting my form so I can have a better UI.
My HTML:
<form id="updateProfileImageForm" enctype="multipart/form-data">
<div class="updateProfileImageContainer">
<img src="images/profile/generic.png" class="updateProfileImage">
<div class="updateProfileImageOverlay" onclick="changeImageToUpload()">
<div class="updateProfileImageOverlayText">Upload new image</div>
</div>
<input type="file" id="imageToUpload" name="image" style="display: none;" onChange="$(this).closest('form').trigger('submit');"></input>
</div>
</form>
My JS:
function changeImageToUpload() {
$('#imageToUpload').trigger('click');
}
$('#updateProfileImageForm').submit(function(e) {
e.preventDefault();
var form_data = new FormData(this);
$.ajax({
type: 'POST',
url: '/changeProfile',
data: form_data,
processData: false,
success: function(response) {
if(response.message != null) {
alert(response.message);
} else {
// Change profile image displayed
$('.updateProfileImage').attr("src", response.newProfileImage);
alert('Profile picture successfully updated! Refresh your browser to update your window!');
}
}
})
});
My Server PHP:
if (isset($_FILES['image'])) {
$image = $_FILES['image'];
}
Var_dump on $_FILES shows an empty array, while var_dump on $_POST shows a lot of information (which I'm assuming is my data file). However, accessing the 'image' property on either $_POST or $_FILES (through either $_POST['image'] or $_FILES['image']) gives me either "undefined index" or "undefined variable".
Would you guys be so kind as to educate me on:
What's the difference between $_POST and $_FILES?
How should I be accessing the file in this case?
Thanks!
You're missing a necessary config option in your ajax request, you need to set contentType to false
$.ajax({
type: 'POST',
url: '/changeProfile',
data: form_data,
processData: false,
contentType: false,
success: function(response) {
if(response.message != null) {
alert(response.message);
} else {
// Change profile image displayed
$('.updateProfileImage').attr("src", response.newProfileImage);
alert('Profile picture successfully updated! Refresh your browser to update your window!');
}
}
})
jQuery.ajax sets the content type by default to application/x-www-form-urlencoded which is incorrect for your FormData object, if you set it to false it will be set correctly by the underlying XMLHTTTPRequest object.
Idea behind it.
Instead of using file as post to PHP, simply convert image to base64 and receive that string using ajax in php.
Refer to this URL
I am trying to make a form where there will be user data(name,dob etc) and an image. When user submits the form a pdf will be generated with the user given data and the image. I can successfully serialize the data but failed to get image in my pdf. I am using simple ajax post method to post data. Below is my code.
HTML code
<form onsubmit="submitMe(event)" method="POST" id="cform">
<input type="text" name="name" placeholder="Your Name" required>
<input type="file" name="pic" id="pic" accept="image/*" onchange="ValidateInput(this);" required>
<input type="submit" value="Preview"/>
</form>
Jquery code
function submitMe(event) {
event.preventDefault();
jQuery(function($)
{
var query = $('#cform').serialize();
var url = 'ajax_form.php';
$.post(url, query, function () {
$('#ifr').attr('src',"http://docs.google.com/gview?url=http://someurl/temp.pdf&embedded=true");
});
});
}
PHP code
<?php
$name=$_POST['name'];
$image1=$_FILES['pic']['name'];
?>
Here I am not getting image1 value. I want to get the url of the image.
You need FormData to achieve it.
SOURCE
Additionally, you need to change some stuff inside ajax call(explained in link above)
contentType: false
cache: false
processData:false
So the full call would be:
$(document).on('change','.pic-upload',uploadProfilePic);
#.pic-upload is input type=file
function uploadProfilePic(e){
var newpic = e.target.files;
var actual = new FormData();
actual.append('file', newpic[0]);
var newpic = e.target.files;
var actual = new FormData();
actual.append('file', newpic[0]);
$.ajax({
type:"POST",
url:"uploadpic.php",
data: actual,
contentType: false,
cache: false,
processData:false,
dataType:"json",
success: function (response){
#Maybe return link to new image on successful call
}
});
}
Then in PHP you handle it like this:
$_FILES['file']['name']
since you named it 'file' here:
actual.append('file', newpic[0]);
When I try to check user input name is already exist by ajax form submit !But it only get Undefined index: username in sessions.php ,what is missing ?
<form action="" method="POST" id="saveuser" enctype="multipart/form-data">
<input type="text" name="username"><br>
<input type="password" name="pass"><br>
<input type="file" name="fileupload"><br>
<input type="submit" name="submit" value="Confirm" id="confirm">
</form>
<script type="text/javascript">
$('#confirm').click(function(e){
e.preventDefault();
$.ajax({
type:'POST',
url :"sessions.php",
data:$("#saveuser").serialize(),
contentType : false,
processData: false,
success: function(d){
console.log(d);//[error] :Undefined index: username
}
});
});
</script>
sessions.php
<?php
$exist = "david";
if($_POST['username'] == $exist){
echo json_encode("Already exist");
}
else{
echo json_encode("You can succesfully add");
}
?>
If you set contentType to false, ajax header is not send, in result if you send somehing type:POST header doesn't contain your data, so server can't see it. If you use GET to do it, it will work, because data is sended with GET (after url) not in header.
Just remove contentType
$.ajax({
type:'POST',
url :"sessions.php",
data: $("#saveuser").serialize(),
success: function(d){
console.log(d);
}
});
contentType
(default: 'application/x-www-form-urlencoded;
charset=UTF-8')
Type: Boolean or String When sending data to the
server, use this content type. Default is
"application/x-www-form-urlencoded; charset=UTF-8", which is fine for
most cases. If you explicitly pass in a content-type to $.ajax(), then
it is always sent to the server (even if no data is sent). As of
jQuery 1.6 you can pass false to tell jQuery to not set any content
type header. Note: The W3C XMLHttpRequest specification dictates that
the charset is always UTF-8; specifying another charset will not force
the browser to change the encoding. Note: For cross-domain requests,
setting the content type to anything other than
application/x-www-form-urlencoded, multipart/form-data, or text/plain
will trigger the browser to send a preflight OPTIONS request to the
server.
processData is used to send data as it is - Ajax documentation
Sending Data to the Server
By default, Ajax requests are sent using the GET HTTP method. If the
POST method is required, the method can be specified by setting a
value for the type option. This option affects how the contents of the
data option are sent to the server. POST data will always be
transmitted to the server using UTF-8 charset, per the W3C
XMLHTTPRequest standard.
The data option can contain either a query string of the form
key1=value1&key2=value2, or an object of the form {key1: 'value1',
key2: 'value2'}. If the latter form is used, the data is converted
into a query string using jQuery.param() before it is sent. This
processing can be circumvented by setting processData to false. The
processing might be undesirable if you wish to send an XML object to
the server; in this case, change the contentType option from
application/x-www-form-urlencoded to a more appropriate MIME type.
There are few issues with your code, such as:
... it only get Undefined index: username in sessions.php
The problem is because of the following two lines,
contentType : false,
processData: false,
From the documentation,
contentType (default: 'application/x-www-form-urlencoded; charset=UTF-8')
Type: Boolean or String
When sending data to the server, use this content type. Default is "application/x-www-form-urlencoded; charset=UTF-8", which is fine for most cases. If you explicitly pass in a content-type to $.ajax(), then it is always sent to the server (even if no data is sent). As of jQuery 1.6 you can pass false to tell jQuery to not set any content type header.
and
processData (default: true)
Type: Boolean
By default, data passed in to the data option as an object (technically, anything other than a string) will be processed and transformed into a query string, fitting to the default content-type "application/x-www-form-urlencoded". If you want to send a DOMDocument, or other non-processed data, set this option to false.
Hence, $_POST array would be empty in sessions.php page if you set contentType and processData to false, and that's why you're getting this undefined index: username error. But having said that, since you're sending a file with your AJAX request, it's okay to set these settings as false, which is further explained in the following point.
.serialize() method creates a URL encoded text string by serializing form control values, such as <input>, <textarea> and <select>. However, it doesn't include file input field while serializing the form, and hence your remote AJAX handler won't receive the file at all. So if you're uploading file through AJAX, use FormData object. But keep in mind that old browsers don't support FormData object. FormData support starts from the following desktop browsers versions: IE 10+, Firefox 4.0+, Chrome 7+, Safari 5+, Opera 12+.
Since you're expecting a json object from server, add this setting dataType:'json' to your AJAX request. dataType is the type of data you're expecting back from the server.
So the solution would be like this:
Keep your HTML form as it is, and change your jQuery/AJAX script in the following way,
$('#confirm').click(function(e){
e.preventDefault();
var formData = new FormData($('form')[0]);
$.ajax({
type: 'POST',
url : 'sessions.php',
data: formData,
dataType: 'json',
contentType: false,
processData: false,
success: function(d){
console.log(d.message);
}
});
});
And on sessions.php page, process your form like this:
<?php
$exist = "david";
if(isset($_POST['username']) && !empty($_POST['username']) && isset($_POST['pass']) && !empty($_POST['pass'])){
if($_POST['username'] == $exist){
echo json_encode(array("message" => "Already exist"));
}else{
echo json_encode(array("message" => "You can succesfully add"));
// get username and password
$username = $_POST['username'];
$password = $_POST['pass'];
// process file input
// Check whether user has uploaded any file or not
if(is_uploaded_file($_FILES['fileupload']['tmp_name'])){
// user has uploaded a file
}else{
// no file has been uploaded
}
}
}else{
echo json_encode(array("message" => "Invalid form inputs"));
}
?>
You are setting contentType to false, that is why PHP can not parse your post body
Use $.post() for ajax :
$('#confirm').click(function(e){
e.preventDefault();
$.post("sessions.php", $.param($("#saveuser").serializeArray()), function(data) { // use this ajax code
console.log(data);
});
});
Use the following code in your html code and remove contentType : false,
processData: false
<form action="" method="POST" id="saveuser" enctype="multipart/form-data">
<input type="text" name="username"><br>
<input type="password" name="pass"><br>
<input type="file" name="fileupload"><br>
<input type="submit" name="submit" value="Confirm" id="confirm">
</form>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.0.0-rc1/jquery.min.js"></script>
<script type="text/javascript">
$('#confirm').click(function(e){
e.preventDefault();
$.ajax({
type:'POST',
url :"sessions.php",
data: $('#saveuser').serialize(),
success: function(d){
console.log(d);//[error] :Undefined index: username
}
});
});
</script>
Considering this is your HTML form
<form method="POST" id="saveuser" enctype="multipart/form-data">
<input type="text" name="username" id="username"><br>
<input type="password" name="pass" id="pass"><br>
<input type="file" name="fileupload"><br>
<input type="submit" name="submit" value="Confirm" id="confirm">
</form>
You can call the jQuery function like this
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.0.0-rc1/jquery.min.js"></script>
jQuery("#saveuser").submit(function () {
//Validate the input here
jQuery.ajax({
type: 'POST',
url: 'sessions.php',
data: jQuery('#saveuser').serialize(),
success: function (msg) {
msg = jQuery.trim(msg);
if (msg == 'Success') {
//Do Whatever
//jQuery("#thanks_message").show('slow');
}
}
});
return false;
});
You will get all the params in your session.php file like
<?php
$username = trim($_POST['username']);
$pass = trim($_POST['pass']);
//rest of the params of the form
$exist = "david";
if ($username == $exist) {
echo json_encode("Already exist");
} else {
echo json_encode("You can succesfully add");
}
?>
I hope this resolves your problem.
<form method="POST" id="saveuser" enctype="multipart/form-data">
<input type="text" name="username"/><br>
<input type="password" name="pass"/><br>
<input type="file" name="fileupload"/><br>
<input type="button" name="save" id="save" value="save"/>
</form>
<script type="text/javascript">
$('#save').click(function(e){
var form = new FormData(document.getElementById('#saveuser'));
$.ajax({
url :"sessions.php",
type : 'POST',
dataType : 'text',
data : form,
processData : false,
contentType : false,
success: function(d){
console.log(d);//[error] :Undefined index: username
}
});
});
</script>
You need to change your script:
Try using new FormData instead of .serialize().
<script type="text/javascript">
$('#confirm').click(function(e){
e.preventDefault();
var formData = new FormData($("#saveuser")[0]);
$.ajax({
type:'POST',
url :"tt.php",
data:formData,
contentType : false,
processData: false,
success: function(d){
console.log(d);//[error] :Undefined index: username
}
});
});
</script>
Note : You are used contentType to false that mean jQuery not to add a Content-Type header. You are using jQuery's .serialize() method which creates a text string in standard URL-encoded notation. You need to pass un-encoded data when using "contentType: false".
Change your script to
<script type="text/javascript">
$(function(){
$('#confirm').click(function(e){
e.preventDefault();
$.ajax({
type:'POST',
url :"sessions.php",
data:$("#saveuser").serialize(),
contentType : false,
processData: false,
success: function(d){
console.log(d);//[error] :Undefined index: username
}
});
});
});
</script>
Your coding is correct.Remove processData and contentType from Ajax it will work
processData : false,
contentType : false,
Remove that method,action: post and blank from your form tag as you need to give all details in ajax method only.
or you can delete the form tag itself as ajax method will take care of the post call.
this will solve hopefully
<form id="saveuser" enctype="multipart/form-data">
I am trying to echo the contents of an input field on enter. I have a text input field that I create here:
echo '<form id="changePassForm" action="" method="post" enctype="multipart/form-data">
<div class="changePass">
<div class="changePassBtn">Change Password</div>
<input class = "passwordText" type="password" placeholder="Password" name="passwordText">
</div>';
The field calls this javascript function correctly:
$(".passwordText").keydown(function(event){
if(event.keyCode == 13){
$.ajax({
url: "../php/passwordchange.php", // Url to which the request is send
type: "POST", // Type of request to be send, called as method
data: new FormData(this), // Data sent to server, a set of key/value pairs (i.e. form fields and values)
datatype: 'text',
contentType: false, // The content type used when sending data to the server.
cache: false, // To unable request pages to be cached
processData:false, // To send DOMDocument or non processed data file it is set to false
success: function(data) // A function to be called if request succeeds
{
console.log(data);
}});
console.log("WORKS!!");
}
});
Which references password change.php here:
<?php
session_start();
echo "Hello world";
$pass=$_POST['passwordText']; //name of input
echo $pass;
/*$dbh = new PDO("mysql:host=localhost;dbname=sqlserver", 'username', 'password');
$dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$checkforpass = "SELECT password FROM sqlserver.accounts WHERE username='".$username."'";*/
?>
I'm not versed in PHP but Hello world is output to console. How can I output/store value of text field in $pass?
Untested, off the cuff:
$(".passwordText").keydown(function(event){
if(event.keyCode == 13){
var pass = $('#changePassForm input').val();
$.ajax({
url: "../php/passwordchange.php", // Url to which the request is send
type: "POST", // Type of request to be send, called as method
data: 'passwordText=' + pass, // Data sent to server, a set of key/value pairs (i.e. form fields and values)
success: function(data) // A function to be called if request succeeds
{
console.log(data);
}});
console.log("WORKS!!");
}
});
Note also that it is dataType: not datatype:, and that dataType only affects returning data not data being sent to PHP
So, get it working simply first (as above), then get fancy with $('#changePassForm').serialize() etc.
Try as follows
$(".passwordText").keydown(function(event){
if(event.keyCode == 13){
var postData = $('#changePassForm').serializeArray();
$.ajax({
url: "../php/passwordchange.php", // Url to which the request is send
type: "POST", // Type of request to be send, called as method
data: postData, // Data sent to server, a set of key/value pairs (i.e. form fields and values)
datatype: 'text',
contentType: false, // The content type used when sending data to the server.
cache: false, // To unable request pages to be cached
processData:false, // To send DOMDocument or non processed data file it is set to false
success: function(data) // A function to be called if request succeeds
{
console.log(data);
}});
console.log("WORKS!!");
}
});
If you want to use FormData, you can see from the manual that the FormData object constructor takes an optional <form> element and you're using this, which refers to $(".passwordText"), which is a jQuery object. You can pass a form element by doing:
var form = document.getElementById("changePassForm");
var fd = new FormData(form);
Putting this all together we would then have:
$(document).ready(function() {
$(".passwordText").keydown(function(event){
if(event.keyCode == 13){
event.preventDefault();
var form = document.getElementById("changePassForm");
var fd = new FormData(form);
$.ajax({
url: "../php/passwordchange.php", // Url to which the request is send
type: "POST", // Type of request to be send, called as method
data: fd, // Data sent to server, a set of key/value pairs (i.e. form fields and values)
dataType: 'text',
cache: false, // To unable request pages to be cached
processData:false, // To send DOMDocument or non processed data file it is set to false
success: function(data) // A function to be called if request succeeds
{
console.log(data);
}});
console.log("WORKS!!");
}
});
});
As an alternative you can manually append any values you want to have sent in the ajax request like this:
var fd = new FormData();
fd.append($(this).attr("name"), $(this).attr("value"));
Disclaimer:
With that said, the FormData interface is only available in IE >= 10, so if you are worried about cross browser compatibility you may want to consider simply using jQuery's serialize() method to send the data. As an added bonus, it's only 1 line of code.:
data: $("#changePassForm").serialize()