- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我有一个向 Django 发送文件的 ajax 请求,它说 csrf token 丢失但我复制了我的其他有效的 ajax 请求。我确定这与尝试传递要上传的文件有关。
我得到一个 403 和 csrf 缺少返回。
基础.html
<script type='text/javascript' src='http://code.jquery.com/jquery-1.8.2.js'></script>
<script type="text/javascript">
$(document).ready(function() {
$("#create_token").click(function() {
var username = document.getElementById("username").value;
$.ajax({
url : "/gettoken/",
type : "POST",
dataType: "json",
data : {
csrfmiddlewaretoken: '{{ csrf_token }}',
create_token: 'create_token',
username: username,
},
success : function(json) {
document.getElementById('output').innerHTML = ('Token: ' + json['token']);
},
error : function(xhr,errmsg,err) {
console.log(xhr.status + ": " + xhr.responseText);
document.getElementById('output').innerHTML = "Token:" + " Request Failed.";
}
});
return false;
});
$("#add_friend").click(function() {
var token = document.getElementById("friend_token").value;
$.ajax({
url : "/addfriend/",
type : "POST",
dataType: "json",
data : {
csrfmiddlewaretoken: '{{ csrf_token }}',
add_friend: token,
},
success : function(json) {
document.getElementById('output').innerHTML = (json['message']);
},
error : function(xhr,errmsg,err) {
console.log(xhr.status + ": " + xhr.responseText);
document.getElementById('output').innerHTML = "Request Failed.";
}
});
return false;
});
$("#uppropic").click(function() {
var file = document.getElementById("profile_pic").files[0];
console.log(file);
$.ajax({
url : "profilepic/",
type : "POST",
dataType: "json",
processData: false,
data : {
csrfmiddlewaretoken: '{{ csrf_token }}',
profile_pic: file,
},
success : function(json) {
document.getElementById('output').innerHTML = (json['message']);
},
error : function(xhr,errmsg,err) {
console.log(xhr.status + ": " + xhr.responseText);
document.getElementById('output').innerHTML = " Request Failed.";
}
});
return false;
});
});
主页.html
{% extends "base.html" %}
{% block title %}
{% for user in user_data %}
{{user.username}}
{%endfor%}
{% endblock %}
{% block content %}
{% for user in user_data %}
Username: {{user.username}}<br>
First Name: {{user.first_name}}<br>
Last Name: {{user.last_name}}<br>
About: {{user.about}}<br>
Title: {{user.title}}<br>
{%endfor%}
Friends:
{% for friend in friend_data %}
{{friend}}<br>
{%endfor%}
{% if is_user_profile %}
<form method='POST' >
{% csrf_token %}
<input type='text' name='friend_token' id='friend_token'>
<button id='add_friend' name = 'add_friend' value='add_friend' > Add Friend </button>
</form>
<form method='POST' >
{% csrf_token %}
<button id='create_token' name = 'create_token' value='create_token' > Create Token </button>
{% for user in user_data %}
<input type='hidden' id='username' value='{{user.username}}'>
{%endfor%}
</form>
<p id='output'>
</p>
{%endif%}
<form method='POST'>
{% csrf_token %}
<input type='file' name='profile_pic' id='profile_pic'>
<button id='uppropic'> Upload Profile Pic</button>
{% for user in user_data %}
<input type='hidden' id='username' value='{{user.username}}'>
{%endfor%}
</form>
<a href="/logout/">Logout</a>
{% endblock %}
View .py
@login_required
@csrf_protect
def upload_profilepic(request):
context = {}
if request.method == 'POST':
post_data = request.POST.copy()
profile_pic = post_data['profile_pic']
print post_data, profile_pic
handle_uploaded_file(request.FILES['file'])
context.update({'message':'You must select a file to upload.'})
return HttpResponse(simplejson.dumps(context), content_type='application/json')
else:
context.update({'message':'You must select a file to upload.'})
return HttpResponse(simplejson.dumps(context), content_type='application/json')
控制台输出
File { name: "10923328_1112855418728180_5377511192406844214_n.png", lastModified: 1421116207673, lastModifiedDate: Date 2015-01-13T02:30:07.673Z, size: 664332, type: "image/png" } home:56
"403:
<!DOCTYPE html>
<html lang="en">
<head>
<meta http-equiv="content-type" content="text/html; charset=utf-8">
<meta name="robots" content="NONE,NOARCHIVE">
<title>403 Forbidden</title>
<style type="text/css">
html * { padding:0; margin:0; }
body * { padding:10px 20px; }
body * * { padding:0; }
body { font:small sans-serif; background:#eee; }
body>div { border-bottom:1px solid #ddd; }
h1 { font-weight:normal; margin-bottom:.4em; }
h1 span { font-size:60%; color:#666; font-weight:normal; }
#info { background:#f6f6f6; }
#info ul { margin: 0.5em 4em; }
#info p, #summary p { padding-top:10px; }
#summary { background: #ffc; }
#explanation { background:#eee; border-bottom: 0px none; }
</style>
</head>
<body>
<div id="summary">
<h1>Forbidden <span>(403)</span></h1>
<p>CSRF verification failed. Request aborted.</p>
</div>
<div id="info">
<h2>Help</h2>
<p>Reason given for failure:</p>
<pre>
CSRF token missing or incorrect.
</pre>
<p>In general, this can occur when there is a genuine Cross Site Request Forgery, or when
<a
href='http://docs.djangoproject.com/en/dev/ref/contrib/csrf/#ref-contrib-csrf'>Django's
CSRF mechanism</a> has not been used correctly. For POST forms, you need to
ensure:</p>
<ul>
<li>Your browser is accepting cookies.</li>
<li>The view function uses <a
href='http://docs.djangoproject.com/en/dev/ref/templates/api/#subclassing-context-requestcontext'><code>RequestContext</code></a>
for the template, instead of <code>Context</code>.</li>
<li>In the template, there is a <code>{% csrf_token
%}</code> template tag inside each POST form that
targets an internal URL.</li>
<li>If you are not using <code>CsrfViewMiddleware</code>, then you must use
<code>csrf_protect</code> on any views that use the <code>csrf_token</code>
template tag, as well as those that accept the POST data.</li>
</ul>
<p>You're seeing the help section of this page because you have <code>DEBUG =
True</code> in your Django settings file. Change that to <code>False</code>,
and only the initial error message will be displayed. </p>
<p>You can customize this page using the CSRF_FAILURE_VIEW setting.</p>
</div>
</body>
</html>
"
在做了一些研究之后,问题与 ajax 请求将文件传递给 django 的方式有关,这导致了我的 csrf 错误。因此,我尝试通过将 csrf token 附加到 formData 来仿效其他人的做法。
这是一个包含 JQuery: post FormData AND csrf token together 的堆栈帖子
以下设置搞乱了 ajax 请求 过程数据:假的, 内容类型:假,
$("#uppropic").click(function() {
var file = document.getElementById("profile_pic").files[0];
console.log(file);
var csrf = '{{ csrf_token }}';
console.log(csrf);
var formData = new FormData(document.getElementById("profile_pic_form"));
formData.append('csrfmiddlewaretoken', csrf );
console.log(formData);
$.ajax({
url : "/profilepic/",
type : "POST",
dataType: "json",
processData: false,
contentType: false,
data : {
csrfmiddlewaretoken: '{{ csrf_token }}',
profile_pic: file,
},
success : function(json) {
document.getElementById('output').innerHTML = (json['message']);
},
error : function(xhr,errmsg,err) {
console.log(xhr.status + ": " + xhr.responseText);
document.getElementById('output').innerHTML = " Request Failed.";
}
});
return false;
});
最佳答案
通常我会在模板未设置 csrf_token
时看到此错误。来自docs
If your view is not rendering a template containing the csrf_token template tag, Django might not set the CSRF token cookie. This is common in cases where forms are dynamically added to the page. To address this case, Django provides a view decorator which forces setting of the cookie:
ensure_csrf_cookie()
.
呈现文件上传表单的页面是否设置了 token ?也许 {% if is_user_profile %}
条件评估为 False
并且未设置 token ?
您可以尝试使用 @ensure_csrf_cookie
如果没有其他帮助,您 View 中的装饰器会呈现文件上传表单。
关于jquery - 文件上传 ajax 请求中缺少 CSRF token ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28401483/
我有以下正则表达式 /[a-zA-Z0-9_-]/ 当字符串只包含从 a 到z 大小写、数字、_ 和 -。 我的代码有什么问题? 能否请您向我提供一个简短的解释和有关如何修复它的代码示例? //var
我是一名优秀的程序员,十分优秀!