I am coding a project using Django when requesting a url I get a weird Not Allowed Mthod(405).
I what is the error about but here is my implementations and details:
urls.py
url(r'^join/',
csrf_protect(UserSignUp.as_view()),
name='sgn_up'),
views.py
class UserSignUp(View):
def post(self, request):
resp_data = {}
try:
print 'sign up================================================'
x = MyUser.objects.get(email=request.POST['email'])
resp_data['message'] = 'signed up before'
return HttpResponse(json.dumps(resp_data), content_type="application/json")
except MyUser.DoesNotExist:
user = MyUser(email=request.POST['email'],
password=request.POST['password'],
first_name=request.POST['firstName'],
last_name=request.POST['lastName']
)
user.save()
#print 'errorize'
user.set_password(request.POST['password'])
user.save()
resp_data[
'message'] = 'please refer to your email for complete registrations'
return HttpResponse(json.dumps(resp_data), content_type="application/json")
HTML/JS
function csrfSafeMethod(method) {
// these HTTP methods do not require CSRF protection
return (/^(GET|HEAD|OPTIONS|TRACE)$/.test(method));
}
var csrftoken = $('input[name="csrfmiddlewaretoken"]').prop('value');
function sameOrigin(url) {
var host = document.location.host; // host + port
var protocol = document.location.protocol;
var sr_origin = '//' + host;
var origin = protocol + sr_origin;
// Allow absolute or scheme relative URLs to same origin
return (url == origin || url.slice(0, origin.length + 1) == origin + '/') ||
(url == sr_origin || url.slice(0, sr_origin.length + 1) == sr_origin + '/') ||
// or any other URL that isn't scheme relative or absolute i.e relative.
!(/^(\/\/|http:|https:).*/.test(url));
}
$.ajaxSetup({
beforeSend: function(xhr, settings) {
if (!csrfSafeMethod(settings.type) && sameOrigin(settings.url)) {
xhr.setRequestHeader("X-CSRFToken", csrftoken);
}
}
});
function ajaxSignIn(){
$.ajax({
url:"{% url 'sgn_in' %}",
type: "POST",
data: $('#sgn-in-form').serialize(),
dataType : "json",
success: function(json){location.reload();},
error: function(xhr, status) {}
});
}
function ajaxSignUp(){
$.ajax({
url:"{% url 'sgn_up' %}",
type: "POST",
data: $('#sgn-up-form').serialize(),
dataType : "json",
success: function(json){location.reload();},
error: function(xhr, status) {}
});
}
Now I send an ajax request (I have included csrftoken) and post method but I get a 405!
I have other ajax post request with csrftokens bur they working as well(e.g. sign-in)!
The most funny thing about this is that when I use Chrome it gives the error and user data also is saved in the DB!!!(this means that the model post method worked!!!) But when using firefox it only gives error!
Does anyone had encountered such problems? I searched alot but found nothing that helps!
Thanks
In your def post you will also have to include the context.
self.object = self.get_object()
context = self.get_context_data(object=self.object)
return self.render_to_response(context)`
Related
I have my Ajax in a jQuery function:
btnApplyConfig.js:
$(".btnApplyConfig").click(function(){
var token = $("input[name=csrfmiddlewaretoken]").val();
// Some other vars I'm sending properly
console.log('token: '+token); //printing correctly
$("#"+frm).submit(function(e){
e.preventDefault();
console.log('Post method via ajax');
$.ajax({
url: '/ajax/validate_config',
type: 'POST',
data: {
'token': token,
//and other stuff I'm sending properly
},
dataType: 'json',
});
});
});
my Django view:
def validate_config(request):
token = request.GET.get('token', None)
#some other vars I've sent ok with ajax
data = {
#some vars
'token': token,
}
if request.method == 'POST':
item = MyClass.objects.filter(my_keyword=my_filter_values).update(my_ajax_values)
return JsonResponse(data)
All the data is being processed properly, the only problem for me is that I'm getting the following error:
Forbidden (CSRF token missing or incorrect.): /ajax/validate_config/
I've put some prints in view in order to check if vars are being sent properly, and yes they are.
How could I handle it?
I checked some tutorials but I couldn't find a solution so far.
A very simpler way
let cookie = document.cookie
let csrfToken = cookie.substring(cookie.indexOf('=') + 1)
$.ajax({
url: 'url/path',
type: 'POST',
headers: {
'X-CSRFToken': csrfToken
}
})
You can use this. You don't have to put anything in your view for it. It will automatically find it.
$.ajax({
url: ,
type: "POST",
data: {
'csrfmiddlewaretoken': $("input[name=csrfmiddlewaretoken]").val()
// plus other data
},
dataType: 'json',
success: ,
});
You probably also want to add if request.is_ajax() to your view.
This was the solution that worked for me in this case:
Added this code before the Ajax code:
function getCookie(name) {
var cookieValue = null;
if (document.cookie && document.cookie !== '') {
var cookies = document.cookie.split(';');
for (var i = 0; i < cookies.length; i++) {
var cookie = jQuery.trim(cookies[i]);
// Does this cookie string begin with the name we want?
if (cookie.substring(0, name.length + 1) === (name + '=')) {
cookieValue = decodeURIComponent(cookie.substring(name.length + 1));
break;
}
}
}
return cookieValue;
}
var csrftoken = getCookie('csrftoken');
function csrfSafeMethod(method) {
// these HTTP methods do not require CSRF protection
return (/^(GET|HEAD|OPTIONS|TRACE)$/.test(method));
}
$.ajaxSetup({
beforeSend: function(xhr, settings) {
if (!csrfSafeMethod(settings.type) && !this.crossDomain) {
xhr.setRequestHeader("X-CSRFToken", csrftoken);
}
}
});
all. I am newest in Django and I have a question. I want learn what I need return to ajax get/post request. I have example, but I know it is not good. Can u please explain me about responses? When, what and why? I did not find any information about it.
When I click on button, object will delete from data base.
This is my ajax request:
function removeProduct(){
$('.btn-remove').click(function(e){
e.preventDefault();
var data = {};
data["csrfmiddlewaretoken"] = $('#quantity_goods [name="csrfmiddlewaretoken"]').val();
var product = $(this);
data.product_id = product.data("product_id");
var url = product.attr("action");
$.ajax({
url: url,
type: 'POST',
data: data,
cache: true,
success: location.reload(),
});
});
}
This is my view:
def remove_product(request):
"""Remove product from basket."""
data = request.POST
product_id = data.get('product_id')
product = ProductInOrder.objects.filter(id=product_id)
product.delete()
return HttpResponse()
Here's how I do it
var username_ok = false;
var email_ok = false;
/*CSRF Code */
function csrfSafeMethod(method) {
// these HTTP methods do not require CSRF protection
return (/^(GET|HEAD|OPTIONS|TRACE)$/.test(method));
}
function sameOrigin(url) {
// test that a given url is a same-origin URL
// url could be relative or scheme relative or absolute
var host = document.location.host; // host + port
var protocol = document.location.protocol;
var sr_origin = '//' + host;
var origin = protocol + sr_origin;
// Allow absolute or scheme relative URLs to same origin
return (url == origin || url.slice(0, origin.length + 1) == origin + '/') ||
(url == sr_origin || url.slice(0, sr_origin.length + 1) == sr_origin + '/') ||
// or any other URL that isn't scheme relative or absolute i.e relative.
!(/^(\/\/|http:|https:).*/.test(url));
}
/* End CSRF Code */
$(function() {
$('#username, #email').focus(function() {
var value = $(this).val();
if (value == 'required') {
$(this).val(null);
}
});
$('#username').change(function() {
var username = $(this).val();
var data = {'username': username};
var csrftoken = $.cookie('csrftoken');
$.ajax({
url: "/ajax_username",
type: "POST",
dataType: 'json',
beforeSend: function(xhr, settings) {
if (!csrfSafeMethod(settings.type) && sameOrigin(settings.url)) {
// Send the token to same-origin, relative URLs only.
// Send the token only if the method warrants CSRF protection
// Using the CSRFToken value acquired earlier
xhr.setRequestHeader("X-CSRFToken", csrftoken);
}
},
data: JSON.stringify(data),
success: function(response){
if (response['status'] == 'ok') {
if (response['exists'] == true) {
$('.username-exists').removeClass('hidden');
username_ok = false;
} else {
$('.username-exists').addClass('hidden');
username_ok = true;
}
}
}
});
/* End Ajax Call */
});
backend
import json
def username_ajax(request):
response = {'status': None}
if request.method == 'POST':
data = json.loads(request.body)
username = data['username']
response['exists'] = bool( User.objects.filter(username=username))
response['status'] = 'ok'
else:
response['error'] = 'no post data found'
return HttpResponse(
json.dumps(response),
content_type="application/json"
)
hope it helps
I tried all the documentation on Django and other answers here in StackOverflow but the result is still (CSRF Token Missing or Incorrect)
So here is my view in views.py:
class MyView(View):
#method_decorator(ensure_csrf_cookie)
def post(self, request, *args, **kwargs):
t = TemplateResponse(request, 'mytemplate.html', data)
t.render()
return JsonResponse({'html' : t.content, 'title' : data['title']})
and this is the ajax in my js file which is in a function for a click event:
$.ajax({
url: window.location.href,
type: 'POST',
data: data,
beforeSend:
function(xhr, settings) {
if (!csrfSafeMethod(settings.type) && !this.crossDomain) {
var token = $.cookie('csrftoken');
console.log(token);
xhr.setRequestHeader("X-CSRFToken", token);
}
},
success:
function(result) {
},
});
The first call is successful but the succeeding call leads to missing token.
For the debugging, I used console.log and it is returning a different token every click.
Add the below code in the script. This will send the csrf token in the request in each ajax request
1. This will allow to get csrf token
// using jQuery
function getCookie(name) {
var cookieValue = null;
if (document.cookie && document.cookie !== '') {
var cookies = document.cookie.split(';');
for (var i = 0; i < cookies.length; i++) {
var cookie = jQuery.trim(cookies[i]);
// Does this cookie string begin with the name we want?
if (cookie.substring(0, name.length + 1) === (name + '=')) {
cookieValue = decodeURIComponent(cookie.substring(name.length + 1));
break;
}
}
}
return cookieValue;
}
var csrftoken = getCookie('csrftoken');
2. This will send csrf token on every ajax request
function csrfSafeMethod(method) {
// these HTTP methods do not require CSRF protection
return (/^(GET|HEAD|OPTIONS|TRACE)$/.test(method));
}
$.ajaxSetup({
beforeSend: function(xhr, settings) {
if (!csrfSafeMethod(settings.type) && !this.crossDomain) {
xhr.setRequestHeader("X-CSRFToken", csrftoken);
}
}
});
3.Now send your ajax request
$.ajax({
url: window.location.href,
type: 'POST',
data: data,
success: function(result) {
console.log(result);
},
});
For more information visit django official documentation
I had a problem getting ajax post data from django backend, I don't know how to pass the value, please help.
In html I have simply this:
<form id="get_vulns_from_family">
<label for="family_content">Enter a family name to display the NVTs</label>
<input id="family_content" />
<input type="submit" value="search" />
</form>
In javascript I wrote this:
$(function() {
$("#get_vulns_from_family").submit(function(event) {
var family_text = $("#family_content").val();
var family_data = {"family": family_text};
$.ajax({
url: "/template_conf/get_vulns_from_family",
type: "POST",
data: family_data,
success: function(response) {
console.log(response);
},
error: function(response) {
console.log("failed!");
}
});
// prevent default posting of form
event.preventDefault();
});
});
In Django method corresponding to url /template_conf/get_vulns_from_family, I tried this:
def get_vuln_from_family(request):
family = request.POST['family']
# some other operations to get value for variable "json_data"
return HttpResponse(simplejson.dumps(json_data))
But django said: MultiValueDictKeyError: "Key 'family' not found in <QueryDict: {}>", which means the POST dictionary is empty.
Am I using the wrong way to get post data? If so what should I do? Thanks.
your url "/template_conf/get_vulns_from_family" is missing a trailing slash. django will typically redirect this to "/template_conf/get_vulns_from_family/", dropping the POST data
If your CSRF enabled then simple ajax post do not work. you will have to add the csrf token and set it to the ajax request header.
For Ajax POST request, you have to pass the CSRF token in as POST data with every POST request. For this reason, you must get CSRF token first. Since you have enabled CSRF protection so you will get the token from csrftoken cookie. The CSRF token cookie is named csrftoken by default. Acquiring the token is very straight forward and it can be achieved using the below code snippet.
function getCookie(name) {
var cookieValue = null;
if (document.cookie && document.cookie != '') {
var cookies = document.cookie.split(';');
for (var i = 0; i < cookies.length; i++) {
var cookie = jQuery.trim(cookies[i]);
if (cookie.substring(0, name.length + 1) == (name + '=')) {
cookieValue = decodeURIComponent(cookie.substring(name.length + 1));
break;
}
}
}
return cookieValue;
}
function csrfSafeMethod(method) {
return (/^(GET|HEAD|OPTIONS|TRACE)$/.test(method));
}
function sameOrigin(url) {
var host = document.location.host; // host + port
var protocol = document.location.protocol;
var sr_origin = '//' + host;
var origin = protocol + sr_origin;
return (url == origin || url.slice(0, origin.length + 1) == origin + '/') ||
(url == sr_origin || url.slice(0, sr_origin.length + 1) == sr_origin + '/') ||
!(/^(\/\/|http:|https:).*/.test(url));
}
$(function() {
$("#person_form_id").submit(function(event){
event.preventDefault();
$.ajax({
type:$(this).attr('method'),
url:"",
data:$(this).serialize(),
success: function(){
$('#message').html("<h2 style='color:green;'>Person Form Submitted!</h2>")
},
error: function(){
$('#message').html("<h2 style='color:red;'>Can't submit form</h2>")
}
});
return false;
});
});
$.ajaxSetup({
beforeSend: function(xhr, settings) {
if (!csrfSafeMethod(settings.type) && sameOrigin(settings.url)) {
// Send the token to same-origin, relative URLs only.
// Send the token only if the method warrants CSRF protection
// Using the CSRFToken value acquired earlier
xhr.setRequestHeader("X-CSRFToken", csrftoken);
}
}
});
I have a problem with using Django CSRF with Ajax. I get a 403 Forbidden. I have done all the CSRF things that I normally do with a non-ajax request, but I still have this problem. I'm thinking this has something to do with the javascript snippet at https://docs.djangoproject.com/en/dev/ref/contrib/csrf/#ajax.
$(document).ajaxSend(function(event, xhr, settings) {
function getCookie(name)
{
var cookieValue = null;
if (document.cookie && document.cookie != '')
{
var cookies = document.cookie.split(';');
for (var i = 0; i < cookies.length; i++)
{
var cookie = jQuery.trim(cookies[i]);
// Does this cookie string begin with the name we want?
if (cookie.substring(0, name.length + 1) == (name + '='))
{
cookieValue = decodeURIComponent(cookie.substring(name.length + 1));
break;
}
}
}
return cookieValue;
}
function sameOrigin(url)
{
// url could be relative or scheme relative or absolute
var host = document.location.host; // host + port
var protocol = document.location.protocol;
var sr_origin = '//' + host;
var origin = protocol + sr_origin;
// Allow absolute or scheme relative URLs to same origin
return (url == origin || url.slice(0, origin.length + 1) == origin + '/') ||
(url == sr_origin || url.slice(0, sr_origin.length + 1) == sr_origin + '/') ||
// or any other URL that isn't scheme relative or absolute i.e relative.
!(/^(\/\/|http:|https:).*/.test(url));
}
function safeMethod(method)
{
return (/^(GET|HEAD|OPTIONS|TRACE)$/.test(method));
}
if (!safeMethod(settings.type) && sameOrigin(settings.url))
{
xhr.setRequestHeader("X-CSRFToken", getCookie('csrftoken'));
}
});
I'm not currently using this snippet, mostly because I don't understand a word of it and I don't know how to incorporate it into my jquery ajax call:
function submit_search()
{
$.ajax({
data: {query: document.search_form.query.value},
datatype: 'json',
success: function(data, textStatus, XMLHttpRequest)
{
if (data)
{
if (check_authentication(data))
{
$("#results").html("");
var results = data[0];
var length = data[1];
for (var index = 0; index < results.length; ++index)
{
var result = results[index];
$("#results").append("<p><a href='/entities/" + result["id"] + "'>" + result["name"] +
"</a><br />" + result["description"] + "</p>");
}
}
else
{
offer_login();
}
}
},
type: 'POST',
url: '/ajax/search',
});
}
Does anyone know how I should go about adding this snippet to my code?
Also tried:
$.ajaxSetup({
beforeSend: function(xhr, settings) {
if (!(/^http:.*/.test(settings.url) || /^https:.*/.test(settings.url))) {
// Only send the token to relative URLs i.e. locally.
xhr.setRequestHeader("X-CSRFToken",
$("#csrfmiddlewaretoken").val());
}
}
});
but this also does not seem to work, although I'm not sure whether I should be doing something for the bit about #csrfmiddlewaretoken in my form
Thanks
All you need to do is paste the code block in such a way that the code in it runs. If you have a global JS file, you should be able to just add that JavaScript to the end of said file, and it will fix the problem.
well, couple steps required as stated in https://docs.djangoproject.com/en/dev/ref/contrib/csrf/
To summarize the tedious django doc, you will need to:
1. install jquery.cookie plugins
2. make sure crsf_token is passing around
for example, in your template, the form must contain the following hidden field
<input type="hidden" name="csrfmiddlewaretoken" value="{{csrf_token}}"/>
In your ajax request, you should so similar things like
csrf_token = $.cookie('csrftoken');
$.ajax({
url: '/url/',
type: 'POST',
beforeSend: function(xhr, settings) {
xhr.setRequestHeader("X-CSRFToken", csrf_token);
},
data: $('.form').serialize(), //assume you are submit a form
}).done(function(response){
console.log(response)
});
one small tricks that you might be missing is, your landing page(non-ajax) will need #csrf_protect decorator to set up cookie, if you don't do that, the cookie won't exists and the method will fail. If you don't want to do #csrf_protect decorator, you can always refer back to the doc and specifically setup the cookie. Either way will work.
Hope this helps.