Javascript 如何在 Dropzone 上传请求的标头中包含 CSRF 令牌?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/30149023/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to include the CSRF token in the headers in Dropzone upload request?
提问by Rohan
I am working on a single page application and I am using Laravel 5 for the web service.
我正在开发一个单页应用程序,我使用 Laravel 5 作为 Web 服务。
All forms are submitted asynchronously and I use a beforeSend on them to attach the CSRF token which I take from the meta tag like so:
所有表单都是异步提交的,我在它们上使用 beforeSend 来附加我从元标记中获取的 CSRF 令牌,如下所示:
$.ajax({
url: '/whatever/route',
type: 'POST',
dataType: 'JSON',
data: $('form#whatever-form').serialize(),
beforeSend: function(request) {
return request.setRequestHeader('X-CSRF-Token', $("meta[name='token']").attr('content'));
},
success: function(response){
rivets.bind($('#whateverTag'), {whateverData: response});
},
error: function(response){
}
});
All my forms work fine but dropzone upload doesn't. It gives me back a TokenMismatchExceptionexception. Here is my dropzone code to update the profile photo:
我所有的表单都可以正常工作,但 dropzone 上传却没有。它给了我一个TokenMismatchException例外。这是我用于更新个人资料照片的 dropzone 代码:
$("#mydropzone").dropzone({
url: "/profile/update-photo",
addRemoveLinks : true,
maxFilesize: 5,
dictDefaultMessage: '<span class="text-center"><span class="font-lg visible-xs-block visible-sm-block visible-lg-block"><span class="font-lg"><i class="fa fa-caret-right text-danger"></i> Drop files <span class="font-xs">to upload</span></span><span>  <h4 class="display-inline"> (Or Click)</h4></span>',
dictResponseError: 'Error uploading file!'
});
I have tried putting the beforeSendin here too:
我也试过把它beforeSend放在这里:
$("#mydropzone").dropzone({
url: "/profile/update-photo",
addRemoveLinks : true,
maxFilesize: 5,
dictDefaultMessage: '<span class="text-center"><span class="font-lg visible-xs-block visible-sm-block visible-lg-block"><span class="font-lg"><i class="fa fa-caret-right text-danger"></i> Drop files <span class="font-xs">to upload</span></span><span>  <h4 class="display-inline"> (Or Click)</h4></span>',
dictResponseError: 'Error uploading file!',
beforeSend: function(request) {
return request.setRequestHeader('X-CSRF-Token', $("meta[name='token']").attr('content'));
},
});
I have also tried to put a global ajaxSetup in my main file like so:
我还尝试将全局 ajaxSetup 放在我的主文件中,如下所示:
$.ajaxSetup({
headers: {
'X-CSRF-TOKEN': $('meta[name="token"]').attr('content')
}
});
It is still not working. What am I doing wrong? How can I pass the CSRF token in the header with the dropzone upload so as to not a get an exception?
它仍然无法正常工作。我究竟做错了什么?如何通过 dropzone 上传在标头中传递 CSRF 令牌,以免出现异常?
回答by Rohan
Okay so this code is working just fine now:
好的,所以这段代码现在工作得很好:
$("#mydropzone").dropzone({
url: "/profile/update-photo",
addRemoveLinks : true,
maxFilesize: 5,
dictDefaultMessage: '<span class="text-center"><span class="font-lg visible-xs-block visible-sm-block visible-lg-block"><span class="font-lg"><i class="fa fa-caret-right text-danger"></i> Drop files <span class="font-xs">to upload</span></span><span>  <h4 class="display-inline"> (Or Click)</h4></span>',
dictResponseError: 'Error uploading file!',
headers: {
'X-CSRF-TOKEN': $('meta[name="token"]').attr('content')
}
});
So basically I needed to add the X-CSRFTokenin the header of the Dropzone request. Works like charm now.
所以基本上我需要X-CSRFToken在 Dropzone 请求的标头中添加。现在像魅力一样工作。
回答by Nyan Lynn Htut
You can add csrf token for every jquery ajax request within your application with these code.
您可以使用这些代码为应用程序中的每个 jquery ajax 请求添加 csrf 令牌。
$.ajaxSetup({
headers: {
'X-CSRF-Token': $('meta[name="_token"]').attr('content')
}
});
回答by Feuda
This also works pretty well :
这也很有效:
$("#mydropzone").dropzone({
url: "/profile/update-photo",
addRemoveLinks : true,
maxFilesize: 5,
dictResponseError: 'Error uploading file!',
headers: {
'X-CSRF-Token': $('input[name="authenticity_token"]').val()
}
});
回答by Jeffrey Chidi
Dropzone.autoDiscover = false;
// or disable for specific dropzone:
// Dropzone.options.myDropzone = false;
$(function () {
// Now that the DOM is fully loaded, create the dropzone, and setup the
// event listeners
var myDropzone = new Dropzone("#my-awesome-dropzone");
myDropzone.on("addedfile", function (file) {
/* Maybe display some more file information on your page */
});
myDropzone.on("sending", function (file, xhr, formData) {
formData.append('csrfmiddlewaretoken', document.getElementsByName('csrfmiddlewaretoken')[0].value);
/* Maybe display some more file information on your page */
});
});
You could include it this way.
你可以这样包含它。
回答by jb0t
I believe the best way to handle this is to set it by default for all ajax posts (with jQuery) as according to the Django docs
我相信处理这个问题的最好方法是根据 Django 文档为所有 ajax 帖子(使用 jQuery)默认设置它
https://docs.djangoproject.com/en/1.8/ref/csrf/#ajax
https://docs.djangoproject.com/en/1.8/ref/csrf/#ajax
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));
}
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));
}
$.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);
}
}
});
In your example, you have a typo when adding it to the Dropzone.js ajax post.
在您的示例中,将其添加到 Dropzone.js ajax 帖子时您有一个错字。
'X-CSRF-Token'
'X-CSRF-Token'
should be
应该
'X-CSRFToken'
'X-CSRFToken'
回答by kiran
We can set CSRF token in request header.
我们可以在请求头中设置 CSRF 令牌。
xhr = open("POST",logURL,true);
//Set CSRF token in request header for prevent CSRF attack.
xhr.setRequestHeader(CSRFHeaderName, CSRFToken);
回答by Steve Bauman
For anyone using default Laravel setup:
对于使用默认 Laravel 设置的任何人:
window.Laravel = {!! json_encode([
'csrfToken' => csrf_token(),
]) !!};
Dropzone.options.attachments = {
url: 'upload',
headers: {
'X-CSRF-TOKEN': Laravel.csrfToken
}
}
回答by Paulo Fidalgo
For those of you that came here and are looking for the Rails solution, add the header with the following code:
对于那些来到这里并正在寻找 Rails 解决方案的人,请使用以下代码添加标题:
headers: {
'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
},
The same applies for Laravel 6.x according to the docs: https://laravel.com/docs/6.x/csrf#csrf-x-csrf-token
根据文档,这同样适用于 Laravel 6.x:https://laravel.com/docs/6.x/csrf#csrf-x-csrf-token
$.ajaxSetup({
headers: {
'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
}
});
回答by liyufeng
you can add a headers.
var myDropzone = new Dropzone("#drop_id", {
url: "/upload/",
headers: {'x-csrftoken': $.cookie('csrftoken')},
method:"post",
...
}

