我正在处理图片上传表单。当用户上传图像时。在预览区域中使用ajax显示该图像...表单重新加载但似乎不想显示新的头像。我收到CSRF verification failed. Request aborted
错误。
Reason given for failure: CSRF is missing or incorrect.
我在表单中有一个csrf_token。
模板:
<form class="nice inline-form" enctype="multipart/form-data" method="POST" action="/profile/edit/" id="avatarLoadForm">
<input type="hidden" name="next" value="/account/settings/">
{% csrf_token %}
<div>
<label for="avatar">Avatar</label>
<div id="preview" class="frame">
<img src="{% if profile.user %}{% thumbnail profile.avatar 120x120 crop %}{% else %}{{ DEFAULT_AVATAR }}{% endif %}" alt="" alt="sample-pic" id="thumb" />
</div>
<input type="file" size="20" id="imageUpload">
and other form info...
</form>
的的Ajax / Jquery的: 的
$(document).ready(function(){
var thumb = $('img#thumb');
new AjaxUpload('imageUpload', {
action: $('#avatarLoadForm').attr('action'),
name: 'avatar',
csrfmiddlewaretoken: $( "#csrfmiddlewaretoken" ).val(),
onSubmit: function(file, extension) {
$('#preview').addClass('loading');
},
onComplete: function(file, response) {
thumb.load(function(){
$('#preview').removeClass('loading');
thumb.unbind();
});
thumb.attr('src', response);
}
});
也许我的 Views.py 中缺少某些内容?
@login_required
def edit_profile(request):
context = base_context(request)
if request.method == 'POST':
notify = "You have successfully updated your profile."
user_info_form = UserInfoForm(request.POST, request.FILES)
if user_info_form.is_valid():
if request.is_ajax():
response = simplejson.dumps({"status": "Upload Success"})
return HttpResponse (response, mimetype='application/json')
messages.success(request, 'You have successfully updated your profile.')
user_info_form.save(request.user, profile_type)
return HttpResponseRedirect(request.POST.get('next', '/profile/' + request.user.username + '/'))
else:
initial = {}
initial['first_name'] = request.user.first_name
initial['last_name'] = request.user.last_name
initial['email'] = request.user.email
initial['about'] = profile.about
initial['country'] = profile.country
initial['about'] = profile.about
user_info_form = UserInfoForm(initial=initial)
context['user_info_form'] = user_info_form
context['profile'] = profile
return render_to_response('settings/profile.html', context, context_instance=RequestContext(request))
的 Settings.py: 的
MIDDLEWARE_CLASSES = (
'django.middleware.common.CommonMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.middleware.csrf.CsrfResponseMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'pagination.middleware.PaginationMiddleware',
)
文件上传没有ajax废话。至于说,它实际上保存了图像,只是没有在预览中显示它。我真的不知道出了什么问题,或者为什么会这样。关于csrf失败的帖子很多。但我找不到一个与这种情况有关的东西。任何见解都会非常感激。
答案 0 :(得分:3)
是什么让您认为csrf令牌的ID为#csrfmiddlewaretoken
?快速查看渲染的html会发现模板标记不会生成id属性。
尝试使用$("input[name=csrfmiddlewaretoken]").val()
答案 1 :(得分:0)
csrfmiddlewaretoken: $( "#csrfmiddlewaretoken" ).val(),
这可能行不通。 CSRF字段的名称/ id是动态生成的,不是像这样的静态字符串。
有关如何正确使用带有AJAX请求的CSRF中间件,请参阅https://docs.djangoproject.com/en/1.3/ref/contrib/csrf/#ajax。
答案 2 :(得分:0)
答案 3 :(得分:0)
这对我有用:
beforeSend: function(jqXHR, settings) {
jqXHR.setRequestHeader('X-CSRFToken', $('input[name=csrfmiddlewaretoken]').val());
},
或者,您可以从dom中提取cookie,如果您的表单是通过ajax生成的,并且由于它呈现的方式而无法发送{{csrf_token}},那么这很好:
beforeSend: function(xhr, settings) {
console.log('-------------before send--');
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;
}
if (!(/^http:.*/.test(settings.url) || /^https:.*/.test(settings.url))) {
// Only send the token to relative URLs i.e. locally.
xhr.setRequestHeader("X-CSRFToken", getCookie('csrftoken'));
}
}