CSRF token missing in Django form submission - javascript

I am trying to submit a form via ajax.My template is as follows:-
<form method="POST" id="form1" class="SignUP signupform">
<div class="classheading">Sign-up</div>
{% csrf_token %}
<input type="text" name="user" placeholder="Username" class="sinput" required="true" />
<input type="text"name="email" placeholder="Email" class="sinput" required="true"/>
<input type="password"name="password"placeholder="Password" class="sinput" required="true"/>
<input type="password"placeholder="Re-enter Password" class="sinput" required="true"/>
<button type="submit" class="subform">Sign Up</button>
</form>
while ajax view submitting this form is:-
$(document).ready(function(){
$('#form1').submit(function(){
console.log('form is submitted');
var csrftoken = $("[name=csrfmiddlewaretoken]").val();
var formdata={
'username':$('input[name=user]').val(),
'email':$('input[name=email]').val(),
'password1':$('input[name=password]').val(),
'password2':$('input[name=password1]').val(),
};
console.log("Formvalue is taken");
$.ajax({
type:'POST',
url:'/Submit/signingup',
data:formdata,
dataType:'json',
encode:true,
headers:{
"X-CSRFToken": csrftoken
},
})
.done(function(data){
console.log(data);
});
event.preventDefault();
});
});
On backend, i'm submitting this form using Django.Corresponding View is as follows:-
#csrf_protect
def signup(request):
if request.method == 'POST':
form = SignupForm(request.POST)
if form.is_valid():
user = form.save(commit=False)
user.is_active = False
user.save()
current_site = get_current_site(request)
mail_subject = 'Activate your blog account.'
message = render_to_string('acc_active_email.html', {
'user': user,
'domain': current_site.domain,
'uid':urlsafe_base64_encode(force_bytes(user.pk)).decode(),
'token':account_activation_token.make_token(user),
})
to_email = form.cleaned_data.get('email')
email = EmailMessage(
mail_subject, message, to=[to_email]
)
email.send()
return HttpResponse("Confirm your email.")
else:
return JsonResponse({'success': False,'errors': [(k, v[0]) for k, v in form.errors.items()]})
But it's showing 403 error.In command prompt, it's showing "CSRF_TOKEN missing or incorrect".
What could be the possible error?

put csrf_token right after from open tag like this. and try
<form method="POST" id="form1" class="SignUP signupform">{% csrf_token %}

try this
$.ajax({
url: url ,
dataType: "json",
type: "POST",
data:{
data: val ,
csrfmiddlewaretoken: "{{ csrf_token }}",
},
success: function(data){
console.log(data)
}
})

Related

AJAX form submission in Django

I keep receiving 'Not Ajax' as a response during my form submission. I have to be missing something small but I cannot see it...
class VideoLikeView(View):
def post(self, request):
if request.is_ajax():
message = 'Ajax'
else:
message = 'Not Ajax'
return HttpResponse(message)
The AJAX code looks like this:
$(function () {
$("#like-form").submit(function (event) {
$.ajax({
type: "POST",
url: form.attr('action'),
headers: {'X-CSRFToken': '{{ csrf_token }}'},
data: {'pk': $(this).attr('value')},
success: function(response) {
alert('Video liked');
},
error: function(rs, e) {
alert(rs.responseText);
}
}
});
});
});
And my HTML:
<form id="like-form" action="{% url 'video-like' %}" method="post">
{% csrf_token %}
<input name="like"
type="hidden"
value="{{ video.id }}">
<button type="submit">
<span class="video-options ml-auto fas fa-heart fa-2x m-2"></span>
</button>
</form>
One question to add to this; how can I use an <input> in my form without using a <button>? I would like to use fontawesome icons but it seems I have to use a button to get the form to submit.
I found one answer on the internet that seems to work but I don't understand what the issue was. Seems like some type of serialization needed (?)... Anyways, here is what worked:
var frm = $('#like-form');
frm.submit(function () {
$.ajax({
type: frm.attr('method'),
url: frm.attr('action'),
data: frm.serialize(),
success: function (data) {
console.log('success');
},
error: function(data) {
console.log('failed');
}
});
return false;
});
Would love to hear from people why this works and not the previous..
try change your btn type button and add ID for event click :
since putting the submit button goes directly to view.py without going through AJAX
<form id="like-form" action="{% url 'video-like' %}" method="post">
{% csrf_token %}
<input name="like"
type="hidden"
value="{{ video.id }}" id="id_pk">
<button type="button" id="id_btn">
<span class="video-options ml-auto fas fa-heart fa-2x m-2"></span>
</button>
in your script
$("#id_btn").click(function() {
$.ajax({
url:window.location.origin + 'your url'
type: 'POST',
data: {'pk':$(#id_pk).val(), 'accion':'guardar'},
success: function (data) {
console.log('success');
},
error: function(data) {
console.log('failed');
}
});
});
and your view.py
def post(self, request):
if 'guardar' in request.POST['accion']:
print("")

How to submit two forms with their Ajax with one button

I have two forms one with product details like price, description and name. And the other with images, they both have different Ajax but they send data to the same route. I want to submit them with one button. So if I click a submit button it should submit all data at once which are price, name, image etc. How can I do this if possible?
Blade file
//Form1
<form id="form1">
<input type="hidden" value="{{csrf_token()}}" id="token"/>
<label for="name">Name</label>
<input type="text" class="form-control" name="name" id="name"
placeholder="Enter product name">
<label for="price">Price</label>
<input type="text" class="form-control" name="price" id="price"
placeholder="Enter product price">
</form>
//Form2
<form id="file_form" method="post" enctype="multipart/form-data">
<input type="hidden" value="{{csrf_token()}}" id="token"/>
<label for="images">Choose Images</label>
<input id="files" type="file" class="" name="files[]" multiple />
</form>
//Submit Button
<input type='button' class="btn btn-primary" value="Submit" id="btn"/>
Javascript
//Form1 javascript
var token = $("#token").val();
$(document).ready(function(){
$("#btn").click(function(){
var url = '{{ route('product.store') }}';
var form = $('form')[0];
var formData = new FormData(form);
formData.append('_token', token);
$.ajax({
url: url,
data: formData,
type: 'POST',
cache: false,
contentType: false,
processData: false,
success:function(data){
if($.isEmptyObject(data.error)){
$("#msg").html("Product has been added successfull");
$("#msg").fadeOut(3000);
}
}
});
});
//Form 2 Javascript
$("#btn").click(function (e) {
e.preventDefault();
file_area = $('.file-area');
progressbar = $('.progress-bar');
status_bar = $('#status');
image_list = $(".image-list");
status_bar.css('display', 'block');
status_bar.html('<div class="fa-3x">' +
'<i class="fas fa-spinner fa-pulse"></i>' +
'</div>');
if (selected_files.length < 1) {
status_bar.html('<li class="error">Please select file</li>')
} else {
var data = new FormData();
data.append('_token', token);
for (var i = 0, len = selected_files.length; i < len; i++) {
data.append('files[]', selected_files[i]);
}
fiel_feild = $('#files');
$.ajax({
url: '{{ route('product.store') }}',
type: 'POST',
data: data,
contentType: false,
cache: false,
processData: false,
success: function (response) {
result = JSON.parse(response);
if (result['status'] == 'error') {
status_bar.html(result['error']);
} else if (result['status'] == 'success') {
selected_files = [];
image_list.html('');
file_area.css('display', 'none');
status_bar.html('<li class="success">File uploaded successfully.</li>');
}
}
});
return false;
}
});

Django: Update Page Information Without Redirecting

I have this code:
html
<form method="post" id="idForm" name="frm1" action = "/myproject/save/"
enctype="multipart/form-data">
{% csrf_token %}
....
<input type="submit" name="save" id="save" value="Save">
</form>
<span class="status">Value: {{ request.mylist}} </span>
js code
$(document).on('submit', '#idForm',function(e){
$.ajax({
type: 'POST',
url: '{% url "myproject:save_form" %}',
data: {},
success:function(json){
$('.status').contents()[0].textContent = data.mylist
},
error : function(xhr,errmsg,err) {
alert("ajax error")
}
});
});
views
if request.method == 'POST' and 'save' in request.POST:
print("runs save form")
mylist= [5]
return JsonResponse({'mylist':mylist})
Question:
When I click on Save button, It is redirected to a page with
{"mylist": [5]}
How can I make it update only the status part, Value?
Use simple a button
<button type="button" onclick="sendData()">Save/button>
instead of this
<input type="submit" name="save" id="save" value="Save">
Make this a function
function sendData(){
$.ajax({
type: 'POST',
url: '{% url "myproject:save_form" %}',
data: {
csrfmiddlewaretoken: '{{ csrf_token }}',
formdata: JSON.stringify($("#idForm").serialize())
},
success:function(json){
let result = json.mylist[0];
$("#status").html(result);
},
error : function(xhr,errmsg,err) {
alert("ajax error")
}
});
}
You should also pass csrfmiddlewaretokentoken in data of ajax to csrf middle trust your request.
You can do the update in ajax success callback.
Update
At server side you can get the serialized data like this
if request.method == 'POST' and 'save' in request.POST:
print("runs save form")
data=json.loads(request.POST.get('formdata'))
mylist= [5]
return JsonResponse({'mylist':mylist})

How to save images that I get in a POST request using ajax?

I am new to Django. I create a form for identification with two fields for upload images - main_photo, profile_photo
I have a Django form that upload images. With the help of ajax FormData() (I'm working with her wrong maybe), I send them to a function via POST request. But I can not store them. Help me.
template
<input type="hidden" name="csrfmiddlewaretoken" value="9S6oPbkHujBnxaKHSxzU5W4mdkEs6Lbbf3g0OIJAk3lBfaMV8bafzpz8QudIuofJ">
9S6oPbkHujBnxaKHSxzU5W4mdkEs6Lbbf3g0OIJAk3lBfaMV8bafzpz8QudIuofJ
<div class="field inline">
<div class="subhead"></div>
<input type="file" name="main_photo" required="" id="id_main_photo">
<label for="foto1" class="id_foto">
<div class="addPhoto">
<div class="button"></div>
</div>
</label>
</div>
<div class="field inline">
<div class="subhead"></div>
<input type="file" name="profile_photo" required="" id="id_profile_photo">
<label for="foto2" class="id_foto">
<div class="addPhoto">
<div class="button"></div>
</div>
</label>
</div>
<div class="center">
<button class="submit mgln" type="button"></button>
</div>
jquery
var token = '{{csrf_token}}';
$('.mgln').on('click', function(){
photo = new FormData();
photo.append('file1', $('input[name=main_photo]').prop('files')[0])
photo.append('file2', $('input[name=profile_photo]').prop('files')[0])
photo1 = photo.getAll('file1')
photo2 = photo.getAll('file1')
data = {
photo1: photo1,
photo2: photo2,
}
console.log(data)
$.ajax({
headers: { "X-CSRFToken": token },
type: "POST",
url: "{% url 'identification_view' %}",
data: data,
processData: false,
contentType: false,
success: function(result) {
alert('Ok.');
},
error: function(result) {
alert('Error.');
}
})
})
views
def identification_view(request):
if request.method == 'POST':
form = IdentificationForm(request.POST, request.FILES)
if request.is_ajax():
print(request.POST.values()) #[]
print(request.FILES.values()) #[]
return HttpResponse('image upload success')
else:
form = IdentificationForm()
identifications = RequestUser.objects.filter(user = request.user)
return render(request, 'accounts/identification.html', {'form': form, 'identifications': identifications})
forms
class IdentificationForm(forms.ModelForm):
class Meta:
model = RequestUser
fields = ('main_photo', 'profile_photo', )
def clean_image(self):
...
def clean_image2(self):
...
view
def identification_view(request):
if request.method == 'POST':
form = IdentificationForm(request.POST, request.FILES)
if request.is_ajax():
print(dir(request.FILES))
main_photo = request.FILES.get('file1')
profile_photo = request.FILES.get('file2')
RequestUser.objects.create(
user = request.user,
main_photo = main_photo,
profile_photo = profile_photo
)
return HttpResponse('image upload success')
else:
form = IdentificationForm()
identifications = RequestUser.objects.filter(user = request.user)
return render(request, 'accounts/identification.html', {'form': form, 'identifications': identifications})
script
var token = '{{csrf_token}}';
$('.mgln').on('click', function(){
formData = new FormData();
formData.append('file1', $('input[name=main_photo]')[0].files[0])
formData.append('file2', $('input[name=profile_photo]')[0].files[0])
$.ajax({
headers: { "X-CSRFToken": token },
type: "POST",
url: "{% url 'identification_view' %}",
data: formData,
processData: false,
contentType: false,
success: function(result) {
alert('ok.');
},
error: function(result) {
alert('error.');
}
})
})

Laravel csrf token mismatch on ajax post a second time

im trying to submit an ajax post in laravel but im having some problem regarding the form's csrf token. In my form, if the conditions i set in my ajax post url has been met the first time the form has been submitted. However if i submit the form and purposely failed the conditions i set in my ajax post url in the first try, If i submit the form again i get a token mismatch exception in my ajax error log. Do i need to refresh the csrf_token every ajax post?
Below is my code
JS
$(document).on('submit','.registration-form',function(e){
e.preventDefault();
var form = $(this);
var form_url = $(this).attr("action");
var form_values = $(this).serialize();
$.ajax({
url:form_url,
type:'POST',
data:form_values,
dataType: 'json',
async:false,
success: function(result){
console.log(result);
if(result['status']==true){
location.href = result['redirect'];
}
else{
form.find(".form-details").show().html(result['message']);
}
},
error: function(ts) {
console.log(ts.responseText)
}
});
});
HTML
<form action="{{ url('login') }}" method="POST" class="registration-form">
{{ csrf_field() }}
<input type="text" name="username" class="input" placeholder="Email">
<input type="password" name="password" class="input" placeholder="Password">
<button class="button is-redbox is-flat is-fullwidth">Login</button>
</form>
Are u sure that each time that is send in ajax?
data: {
"_token": "{{ csrf_token() }}",
}
$("#cform")[0].reset();
or in plain javascript:
document.getElementById("cform").reset();
public function regenerateToken(){
session()->regenerate();
return response()->json([
'msg'=>'success',
'token'=>csrf_token()
]);
}
$('#form').submit(funtion(event) {
event.preventDefault(event);
// Submit the form using AJAX.
$.ajax({
type: 'POST',
url: form.attr('action'),
data: formData
})
.done(function(response) {
// Make sure that the formMessages div has the 'success' class.
if (response.msg === 'success') {
$('#token').val(response.token);
console.log($('#token').val());
}
}
$('input[type="text"],input[type="email"] ,textarea, select').val(''); $(this).trigger('reset');
});

Categories