我有一个非常简单的表单,我已经添加了上传器。当我调用上传器时,django返回 {“detail”:“CSRF失败:CSRF令牌丢失或不正确。”} 这是上传者:
var ul = new Uploader(
{
label:"Programmed uploader",
multiple:false,
uploadOnSelect:true,
url:Environment.apiRoot + "upload/",
headers:{
"Accept" : "application/json",
"X-CSRFToken" : dojo.cookie("csrftoken")
}
}).placeAt(form);
我创建了一个简单的“测试”按钮,用于调用执行相同帖子的函数。
new Button({
name:"Cancel2",
//id:"Cancel",
label:"Cancel" ,
placement:"secondary",
onClick:lang.hitch(this,function(event){
this._testpost()
})
}).placeAt(form);
这是上传者帖子
的相关标题Cookie djdt = hide; csrftoken = WwlARc9OUevblKfgNEDU2Ae4eT9z0kos;的sessionid = du37rjyam6v69mw0bgctkbw708xlvc5g
这是_testpost()
_testpost: function (){
xhr.post({
url: Environment.apiRoot + "upload/",
handleAs: "json",
postData: json.stringify(data),
headers: {
"Content-Type": "application/json",
"Accept" : "application/json",
"X-CSRFToken" : dojo.cookie("csrftoken")
},
loadingMessage: "Submitting form..."
}).then(
lang.hitch(this,function(result) {
form = t._f_form;
dojo.destroy(form);
this._float.destroyRecursive();
alert(result['result_text']);
result['message'] = "Update Request Accepted";
}),lang.hitch(this, function(err){
form = t._f_form;
dojo.destroy(form);
this._float.destroyRecursive();
topic.publish("/application/message","An error occurred.");
}));
这是调用_testpost函数的相关标题
Cookie djdt = hide; csrftoken = WwlARc9OUevblKfgNEDU2Ae4eT9z0kos;的sessionid = du37rjyam6v69mw0bgctkbw708xlvc5g
X-CSRFToken WwlARc9OUevblKfgNEDU2Ae4eT9z0kos
关键区别在于_testpost中X-CSRFToken被放入标题中,但在Uploader帖子中,我没有办法放入X-CSRFToken(我的标题属性似乎只是被忽略了) - 我试着看看我是否可以让它工作)
有没有办法让其他标题进入上传程序
答案 0 :(得分:0)
不幸的是,dojox.form.Uploader不允许添加标题。
有几种选择。听起来您可以访问csrf令牌并将其附加到URL。另一种选择可能是将csrf令牌作为cookie提供,它应该与XHR和Flash请求一起发送。
答案 1 :(得分:0)
我所做的(并且我不确定这是正确的),在django视图中,禁用csrf检查,然后从标头中提取csrf值并将其与保留的csrf值进行比较在服务器上的会话记录中。
答案 2 :(得分:0)
您可以使用dojo.aspect
将标头添加到dojo.form.Uploader
。
如果您使用HTML5上传"插件",看起来就像您已经离开默认设置一样,您可能会使用以下内容:
aspect.after(ul, "createXhr", function(xhr) {
xhr.setRequestHeader("Accept", "application/json");
xhr.setRequestHeader("X-CSRFToken", dojo.cookie("csrftoken"));
return xhr;
});
在创建上传器后立即添加。还记得要求dojo/aspect
。
请注意,如果dojo.form.Uploader
结构中发生某些更改(例如,他们将其更新为使用dojo.promise
或其他修补程序),则这有点破解且容易破损。此外,它暗示这仅适用于HTML5插件,但您可以通过检查ul.uploadType
以及针对该插件进行特定更改来以相同方式扩展代码以应对其他插件。