Ajax post for django form not working - django

For some reason I cannot get a successful post when trying to use ajax. The code I am trying is here:
http://jsfiddle.net/MRKNq/11/
$('#register_form').submit(function(e) {
$.ajax({
type: "POST",
url: "/echo/json/",
data: $('#register_form').serialize(),
success: function(data) {
alert(data.text);
$('#result').text(data.text);
},
type: 'POST'
});
e.preventDefault();
});​
Any suggestions would be greatly appreciated.

You should look at the response that comes back in Firebug or some other tool. This likely has to do with CSRF.
Have a look at this: https://docs.djangoproject.com/en/dev/ref/contrib/csrf/#ajax
You can also exempt your view from CSRF protection by using this decorator: https://docs.djangoproject.com/en/dev/ref/contrib/csrf/#django.views.decorators.csrf.csrf_exempt

Related

Django - 403 (Forbidden): CSRF token missing or incorrect with Ajax call. Tried everything

I know this is a well worn question and I scoured the web and this website finding countless answers that boil down to the very same solutions and none of them worked for me and I do not know why. my info/trials so far:
suprisingly the csrf_exempt decorator does not work
tried setting up Headers/beforeSend once before all Ajax calls, it does not work (I tried setting the headers both in call and just once for all the ajax calls)
I can pick up the django token easily both via javascript or via django {{ token }}
django.middleware.csrf.CsrfViewMiddleware is present in the settings.py
python 3.8; django 2.2
[UPDATE] I tried removing contentType to no avail as well
here below you can see the different trials in /*...*/
var csrftoken = '{{ csrf_token }}'
$.ajaxSetup({
crossDomain: false,
beforeSend: function(xhr, settings) {
xhr.setRequestHeader("X-CSRFToken", csrftoken)
}
});
$.ajax({
url: '/do_things/',
type: 'POST',
contentType: 'application/json',
data: {
/*'csrfmiddlewaretoken': csrftoken*/
},
beforeSend: function (xhr) {
/*xhr.setRequestHeader('X-Requested-With', 'XMLHttpRequest');*/
/*xhr.setRequestHeader('X-CSRFToken', csrftoken);*/
/*xhr.setRequestHeader('X-CSRF-Token', csrftoken);*/
},
headers: {
/*'X-CSRFToken': csrftoken,*/
/*'X-CSRF-Token': csrftoken*/
},
success: function (data) {
console.log('Fill all the tables')
}
})
on the view side
#login_required(login_url='/login/')
def do_things(request):
if request.method == "POST":
...
on the url side ( in case I messed up something here):
urlpatterns = [
#...
path('r/', views.do_things, name='do_things'),
]
Resources:
a) Forbidden (CSRF token missing or incorrect.) | Django and AJAX
b) Adding CSRFToken to Ajax request
c) https://docs.djangoproject.com/en/2.2/ref/csrf/
let csrftoken = '{{ csrf_token }}'
$.ajax({
type: "POST",
headers:{'X-CSRFToken':csrftoken},
url: "{% url 'Wishlist' %}",
data: {'product_id':product_id},
success: function (response) {
console.log(response, typeof(response))
}
})
I used simple ajax with csrf in the header and it's working fine.
when i use your code in mine, so function calls but data gets blank. i have refered this Django csrf token for Ajax

DJANGO POST GET not working after i18n translation

I have multiple POST requests from my template for example:
$.ajax({
url: '/apply_payment',
type: 'POST',
data: {
basket: JSON.stringify(basket),
key: $('#key_input').val(),
csrfmiddlewaretoken: CSRF_TOKEN
},
dataType: 'json',
success: function (data) {
$("#key_input").val("");
},
...
I read in the basket data in a view.py like this:
basket = request.POST.get('basket', '')
In the urls.py I have these urls in the form of:
path('apply_payment', entrance_api.apply_payment, name='apply_payment'),
Now lately I added i18n_patterns into the URLs, and translated all of my pages, however the AJAX calls stopped working. I guess it is becase the URLs are dynamically changing between selected languages, but I might be wrong.
For example the shows basket variable is always None in the view now. How can I fix this?
From my experience, I had to prepend a language code to the POST request URL:
$.ajax({
url: '/en/apply_payment', // prepend a language code or even better: use window.location.href
type: 'POST',
data: {
basket: JSON.stringify(basket),
key: $('#key_input').val(),
csrfmiddlewaretoken: CSRF_TOKEN
},
dataType: 'json',
success: function (data) {
$("#key_input").val("");
},

flask endpoint for ajax call

I'm making an ajax call to my server while pressing submit button.
Button is present in page http://127.0.0.1:5000/post/15.
Jquery function invoked and the endpoint definition for submit_comment in python respectively:
function submit_comment(post_id) {
var uname = $('input[name="uname"]').val();
var comment = $('textarea[name="comment"]').val();
$.ajax({
url: "/submit_comment",
data: {name: uname, comment: comment, post_id: post_id},
method: "POST",
datatype: 'json',
success: function(response) {
console.log('reaches here');
addElement(response);
console.log('Is it me');
},
error: function(error) {
console.log('reached Error');
console.log(error);
}
});
}
py
#main.route('/submit_comment', methods = ['POST', 'PUT'])
def submit_comment():
entry = request.get_json(force=True)
print 'comment:', entry
....
Main is the blueprint. But I'm getting following 404 error.
127.0.0.1 - - [24/Aug/2017 10:30:55] "POST /post/submit_comment HTTP/1.1" 404 -
I am wondering from where this post got appended into the endpoint.
Can someone help me to understand the error and resolve it?
Thanks,
Deepak
I don't know a lot, but I know that the Flask docs on ajax say to query for the script root like this:
$SCRIPT_ROOT = {{ request.script_root|tojson }};
and then use that as part of the request URL.
An example from an ajax call I've used ($.getJSON being a jquery function for $.ajax)
$.getJSON($SCRIPT_ROOT + '{{ url_for("help_email") }}',

csrf_token of Django into Vuejs when seperate them

I am using ajax request to send POST but it got response 403 because of csrf_token. I divide the frontend just using Vuejs and backend using Django to just reponse API only so I can't use Django template to render {% csrf_token %} or having csrftoken in session to use getcookie('csrftoken') like in Django's doc recommend. Is there anybody face this problem like me and got some solutions ? So thank you if you can help me this.
You can set the CSRF token in the header of your AJAX request. E.g., if you use jquery and jquery.cookie library, you can easily retrieve the Django-set csrftoken cookie like so:
$.ajax({
url : 'YOUR_URL_HERE',
headers: {'X-CSRFToken': $.cookie('csrftoken')},
type: 'POST',
dataType: 'json',
data: {},
success: function() {
},
error: function(xhr, errMsg, err) {
},
});
Django documentation also includes a section on this: https://docs.djangoproject.com/en/1.11/ref/csrf/#ajax
Please note that this solution may depend on your specific Django settings. The Django documentation link above details everything pretty clearly.
EDIT:
Given that even your initial page request is not served by Django, here is how you can accomplish what you're looking for...
1.) Create a view in your Django app that manually generates and returns a CSRF token (using django.middleware.csrf.get_token):
def get_csrf_token(request):
token = django.middleware.csrf.get_token(request)
return JsonResponse({'token': token})
2.) You would also need to add an appropriate entry in your Django URLs file:
url(r'^get-token/$', get_csrf_token)
3.) Then your Vue.js app can fetch the CSRF token using this endpoint. This doesn't need to be a user-initiated event; for example, you can configure your front-end app to fetch it on the $(document).ready() event. Then, using your preferred AJAX library (I am using jQuery in my example):
$.ajax({
url: '/get-token/',
type: 'GET',
dataType: 'json',
success: function(data) {
$.cookie('csrftoken', data.token); // set the csrftoken cookie
}
});
4.) Now your csrftoken cookie is set and should be usable for subsequent POST requests.
$.ajax({
url : 'YOUR_URL_HERE',
headers: {'X-CSRFToken': $.cookie('csrftoken')},
type: 'POST',
dataType: 'json',
data: {},
success: function() {
},
error: function(xhr, errMsg, err) {
},
});
I have used jQuery for AJAX functionality and the jQuery.cookie library for getting and setting cookies, but of course you can use whichever library you would prefer for these functions.
According to the Django documentation you can simply use the ensure_csrf_cookie decorator on a view and that will send the cookie with the token with the response.
This is going to be wildly unpopular, but I've found it to be a relatively simple, secure and unobtrusive way to separate the front/backend.
In your VueJS app, you've probably got a login redirect when the user tries to access a page and are unauthenticated.
So instead of sending it to a vue router page, redirect it to /account/login/ (or some django app route - put an exception in cloudfront, or nginx proxy for /account/login/ to proxy pass to django) - then in the login.html template, just use a javascript window.location.href to your vueJS login page /login
The csrf_token will be set as a HttpOnly, secure cookie (which is what you want), and the disruption to the user is so minimal as to not even justify worrying about.

Using ember data to save multiple records via post

Does anyone know of any working examples of overriding ember-data's DS.Adapter to save all records at once?
I'd like to stringify my entire array of records and send them to my server. I don't have much flexibility on the server to use anything but the existing API which is just a perl CGI script. Any help in the right direction would be appreciated.
What I did was iterate over the ember-data models, serialized them, saved them into a json object that matched server requirements, and executed post request.
var identifiedResponse = []
this.store.filter(key, function (record) {
return !!record.get('name')
}).then(function(resp) {
identifiedResponse.push(item.serialize())
})
jQuery.ajax({
url: url,
type: "POST",
data: identifiedResponse,
contentType: "application/json",
dataType: 'json',
xhrFields: {
withCredentials: true
}
})