Reputation: 2452
AoA I am new to Django, I am trying to get data from POST, but getting error CSRF cookie not set, I tried alot to find the solution on google and stackoverflow via google too, but failed
here is the code
from django.http import HttpResponse
from django.template.loader import get_template
from django.template import Context
from django.template import RequestContext
from django.core.context_processors import csrf
from django.shortcuts import render_to_response
def search_Post(request):
if request.method == 'POST':
c = {}
c.update(csrf(request))
# ... view code here
return render_to_response("search.html", c)
def search_Page(request):
name='Awais you have visited my website :P'
t = get_template('search.html')
html = t.render(Context({'name':name}))
return HttpResponse(html)
<p>
{{ name }}
<form method="POST" action="/save/">
{% csrf_token %}
<textarea name="content" rows="20" cols="60">{{content}}</textarea><br>
<input type="submit" value="Save Page"/>
</form>
<div> Cant figure out any solution! :( </div>
</p>
url(r'^home/$', 'contacts.views.home_Page'),
url(r'^save/$', 'contacts.views.search_Post'),
url(r'^edit/$', 'contacts.views.edit_Page'),
url(r'^search/$', 'contacts.views.search_Page'),
TEMPLATE_CONTEXT_PROCESSORS = (
'django.core.context_processors.csrf',
'django.contrib.auth.context_processors.auth',
'django.core.context_processors.debug',
'django.core.context_processors.i18n',
'django.core.context_processors.media',
'django.core.context_processors.static',
'django.core.context_processors.request',
'django.contrib.messages.context_processors.messages'
)
MIDDLEWARE_CLASSES = (
'django.middleware.common.CommonMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
# Uncomment the next line for simple clickjacking protection:
# 'django.middleware.clickjacking.XFrameOptionsMiddleware',
)
Upvotes: 4
Views: 20144
Reputation: 340
I had the same problem, and resolved it by adding the ensure_csrf_cookie decorator to your view:
from django.views.decorators.csrf import ensure_csrf_cookie
@ensure_csrf_cookie
def yourView(request):
#...
It will set csrftoken in browser cookie and you can make ajax like this
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 csrfSafeMethod(method) {
// these HTTP methods do not require CSRF protection
return (/^(GET|HEAD|OPTIONS|TRACE)$/.test(method));
}
$.ajaxSetup({
crossDomain: false, // obviates need for sameOrigin test
beforeSend: function(xhr, settings) {
if (!csrfSafeMethod(settings.type)) {
xhr.setRequestHeader("X-CSRFToken", getCookie('csrftoken'));
}
}
});
$.ajax({
url: url,
type: type,
async: async,
data: data,
error: function (e) {},
success: function (data) {
returnFunction(data);
}
});
Upvotes: 9
Reputation: 794
Try using the exact IP address with the port number instead of the DNS... Like instead of localhost use 127.0.0.1 along with the port number.
Upvotes: -4
Reputation: 48357
You use both means to pass CSRF token to template processor
c = {}
c.update(csrf(request))
and RequestContext, while one is enough, see docs. But you use it wrong place, for serving 'POST' request. Those requests are normally sent by your browser when it fills up a form and want to get results.
Your browser renders home.html sending GET request to a server, which is served by
t = get_template('home.html')
html = t.render(ResponseContext({'name':name}))
return HttpResponse(html)
part of your code. And there you do not use any mean to pass csrf token. So when your template processor get_template().render()
is invoked, is has no token in its context, so simply ignores {% csrf_token %} code in template. So you have to either use RequestContext
in t.render(...) part of view, or pass you c
dict there.
You can check it inspecting generated form in a browser window.
UPDATE
In seetings.py
add a comma after 'django.core.context_processors.csrf'
, the way it is now, it just contcatenates strings.
Should be:
TEMPLATE_CONTEXT_PROCESSORS = (
'django.core.context_processors.csrf',
'django.contrib.auth.context_processors.auth',
'django.core.context_processors.debug',
Upvotes: 5
Reputation: 4182
It seems that You have forgot to pass request to render
Django comes with a special Context class, django.template.RequestContext, that acts slightly differently than the normal django.template.Context. The first difference is that it takes an HttpRequest as its first argument. For example:
In addition to these, RequestContext always uses django.core.context_processors.csrf. This is a security related context processor required by the admin and other contrib apps, and, in case of accidental misconfiguration, it is deliberately hardcoded in and cannot be turned off by the TEMPLATE_CONTEXT_PROCESSORS setting.
So What You need is following
t = get_template('home.html')
c = RequestContext(request, {'name':name})
return HttpResponse(t.render(c))
If You wold like You can check django dock here https://docs.djangoproject.com/en/dev/ref/templates/api/#django.template.RequestContext
Upvotes: 1
Reputation: 3407
Start from fixing your HTML (You forgot =):
<form method="POST" action="/search/save">
{% csrf_token %}
<textarea name="content" rows="20" cols="60">{{content}}</textarea><br>
<input type="submit" value="Save Page"/>
</form>
Also:
def home_Page(request):
#if request.method == 'GET':
name='Awais you have visited my website :P'
if request.method == 'POST':
#name = request.POST.get('content')
return render_to_response("search.html", {}, context_instance=RequestContext(request))
return render_to_response("home.html", {'name':name}, context_instance=RequestContext(request))
Upvotes: 1