Laravel - Tokenmissmatchexception with Dropzone.js - javascript

I'm using dropzone.js for uploading images to my site, but Laravel always reports TokenMismatchException although I'm using Form::open() in form, which automatically adds _token.
This is my code:
{{ Form::open(["class" => "dropzone", "id" => "imgUpload", "action" => "UploadsController#uploadImage"]) }}
<div class="fallback">
{{ Form::submit() }}
</div>
{{ Form::close() }}
js
Dropzone.options.imgUpload = {
paramName: "file",
dictDefaultMessage: "Pošalji sliku",
acceptedFiles: "image/*",
previewsContainer: ".dropzone-previews",
uploadprogress: function(progress, bytesSent){
console.log(progress);
}
};
How to solve this?

It would appear as though Dropzone does not include the token when posting via AJAX. You can use something like this to make it do so....
Dropzone.options.imgUpload = {
paramName: "file",
dictDefaultMessage: "Pošalji sliku",
acceptedFiles: "image/*",
previewsContainer: ".dropzone-previews",
uploadprogress: function(progress, bytesSent) {
console.log(progress);
},
sending: function(file, xhr, formData) {
// Pass token. You can use the same method to pass any other values as well such as a id to associate the image with for example.
formData.append("_token", $('[name=_token']).val()); // Laravel expect the token post value to be named _token by default
}
};
I found that snippet here... http://laravel.io/forum/04-17-2014-tokenmismatchexception-with-dropzonejs
It also looks like there are some problems with tokens and forms being submitted via AJAX. In that case, you will want to include the additional header when initializing dropzone.
Dropzone.options.imgUpload = {
paramName: "file",
dictDefaultMessage: "Pošalji sliku",
acceptedFiles: "image/*",
previewsContainer: ".dropzone-previews",
headers: {
"X-CSRF-Token": $('[name=_token').val())
},
uploadprogress: function(progress, bytesSent) {
console.log(progress);
}
};
And to utilize this, modify your CSRF filter in filters.php to check for that header if we are submitting via AJAX.
Route::filter('csrf', function()
{
$token = Request::ajax() ? Request::header('X-CSRF-Token') : Input::get('_token');
if (Session::token() != $token) {
throw new Illuminate\Session\TokenMismatchException;
}
});

Related

Dropzone is not working on server. Working fine on localhost

I would like to upload images by using dropzone. It is working fine on localhost. I am able to upload files. But when I uploaded my code server it is not initializing. I am triggering event on click of button.
My code -
//other fields
<div class="dropzone" id="addProductDropzoneNew"></div>
//other fields
Js -
Dropzone.options.addProductDropzoneNew= {
url: '/admin/product/store',
autoProcessQueue: false,
uploadMultiple: true,
parallelUploads: 5,
maxFiles: 5,
maxFilesize: 1,
acceptedFiles: '.jpeg,.jpg,.png,.PNG',
addRemoveLinks: true,
init: function() {
dzClosure = this;
document.getElementById("new-product-btn").addEventListener("click", function(e) {
e.preventDefault();
e.stopPropagation();
if (dzClosure.getQueuedFiles().length === 0) {
var blob = new Blob();
blob.upload = { 'chunked': dzClosure.defaultOptions.chunking };
dzClosure.uploadFile(blob);
} else {
dzClosure.processQueue();
}
});
this.on("sendingmultiple", function(data, xhr, formData) {
formData.append("_token", jQuery("#token").val());
formData.append("id", jQuery("#productId").val());
formData.append("name", jQuery("#name").val());
formData.append("sku", jQuery("#sku").val());
formData.append("menuId", jQuery("#menuId").val());
formData.append("categoryId", jQuery("#category").val());
formData.append("subCategory", jQuery("#sub").val());
formData.append("price", jQuery("#price").val());
formData.append("discount", jQuery("#discount").val());
formData.append("stock", jQuery("#stock").val());
formData.append("color", jQuery("#color").val());
formData.append("size", jQuery("#size").val());
formData.append("height", jQuery("#height").val());
formData.append("width", jQuery("#width").val());
formData.append("weight", jQuery("#weight").val());
formData.append("description", jQuery("#description").val());
formData.append("isPublish", jQuery("#isPublish").val());
formData.append("isB2B", jQuery("#isB2B").val());
formData.append("title", jQuery("#title").val());
formData.append("keyword", jQuery("#keyword").val());
formData.append("metaDescription", jQuery("#metaDescription").val());
formData.append("brandId", jQuery("#brandId").val());
formData.append("isFreeShipping", jQuery("#shipping").val());
});
},
success: function(data)
{
clearError();
if(data.status=='success'){
location.href='/admin/product';
} else {
displayError(data.xhr.response);
}
}
}
I am not sure but it is working fine on local. But i guess it is not initializing on server.
Here is screenshot of local -
This is a screenshot of dropzone div on server -
Also, in developer console log not getting any error. Please check image -
Thank you for your help in advance.

Dropzone.js - Laravel | 500 Internal Server Error

I want to upload my images with dropzone.js, I get images on server side, its ok. But When I want to try save, it gives 500 internal server error.
Dropzone.options.mDropzoneTwo = {
paramName: "file", // The name that will be used to transfer the file
maxFiles: 10,
maxFilesize: 10, // MB
url: 'images/save' ,
method: 'POST',
headers: {
"X-CSRF-TOKEN": document.head.querySelector("[name=csrf-token]").content
},
uploadMultiple: true,
accept: function(file, done) {
done();
},
success: function () {
console.log()
}
};
And here is my controller. I'm saving images to public/uploads folder.
$realname = str_slug(pathinfo($request->file('file')->getClientOriginalName(), PATHINFO_FILENAME));
$extension = $request->file('file')->getClientOriginalExtension();
$new_name = $realname."-".time().".".$extension;
$request->file('file')->move(public_path('uploads/'.str_slug($new_name)));
$image = new Media();
$image->image = str_slug($new_name);
$image->image_path = "images/".str_slug($new_name);
$image->image_alt_name = $realname;
$image->save();
As per comments --
It means your application is not getting file object on $request->file('file') this, you can get more info by printing $request and then you can check for file too weather its being sent from client script or not

Dropzone stops on the progress bar

This will be hard to explain, because I have no live demo. I use a simple dropzone.
HTML:
<form action="http://localhost/upload.php" class="dropzone" method="post" id="upload-widget"></form>
JavaScript:
Dropzone.options.uploadWidget = {
uploadMultiple: false,
maxFilesize: 2, // MB
maxFiles: 1,
acceptedFiles: 'image/*',
init: function() {
this.on('success', function() {
alert('OK);
});
}
};
upload.php file:
if(!empty($_FILES)){
$targetDir = "uploads/";
$fileName = $_FILES['file']['name'];
$targetFile = $targetDir.$fileName;
if(move_uploaded_file($_FILES['file']['tmp_name'],$targetFile)){
//insert file information into db table
}
}
When I pick or drop a file, it will upload, but stops at the progress:
I have no idea, why. When I upload any file, file appear in the /uploads/ folder, but seems like dropzone.js doesn't react on complete. Do I need to print some data? I used this website as tutorial http://www.codexworld.com/drag-and-drop-file-upload-using-dropzone-php/
I found the problem. I'm using this PHP debugger: https://github.com/JosephLenton/PHP-Error which for some unknown reasons disabled receiving XHTTP responses (funny that my website is almost whole in ajax and I haven't noticed any error). Anyway, I can't use dropzone.js with this debugger. I can live with that (also it is turned off when it will go to production).
Try to use the success event like that :
Dropzone.options.uploadWidget = {
uploadMultiple: false,
maxFilesize: 2, // MB
maxFiles: 1,
acceptedFiles: 'image/*',
success: function(file, res) {
console.log('Upload success.');
console.log(res);
},
error: function(file, res) {
console.log('Upload error.');
console.log(res);
}
};

Laravel TokenMismatchException and dropzone

I'm trying to upload pictures via dropzone, but I get tokenmismatch error even tho I added csrf token everywhere needed, i'm getting quite desperate...
My form
{!! Form::open(['route' => 'photo.upload', 'id' => 'hello', 'method' => 'POST', 'class' => 'dropzone no-margin dz-clickable']) !!}
<div class="dz-default dz-message"><span>Drop files here to upload</span></div></form>
{!! Form::close() !!}
my script
Dropzone.autoDiscover = false;
Dropzone.options.hello = {
paramName: "file", // The name that will be used to transfer the file
maxFilesize: 5, // MB
parallelUploads: 2, //limits number of files processed to reduce stress on server
addRemoveLinks: true,
headers: {
'X-CSRF-Token': $('meta[name="csrf-token"]').attr('content'),
},
accept: function(file, done) {
// TODO: Image upload validation
done();
},
sending: function(file, xhr, formData) {
// Pass token. You can use the same method to pass any other values as well such as a id to associate the image with for example.
formData.append("_token", $('input[name="_token"]').val() ); // Laravel expect the token post value to be named _token by default
},
init: function() {
this.on("success", function(file, response) {
// On successful upload do whatever :-)
});
}
};
// Manually init dropzone on our element.
var myDropzone = new Dropzone("#hello", {
url: $('#hello').attr('action')
});
Request headers
...
X-CSRF-Token:P4wc9NVVZJe1VjalPwO6d6WQXZ9eEqPd84ICpToG
...
Request Payload
------WebKitFormBoundarySKMUFNO6dbgzeQVK
Content-Disposition: form-data; name="_token"
P4wc9NVVZJe1VjalPwO6d6WQXZ9eEqPd84ICpToG
------WebKitFormBoundarySKMUFNO6dbgzeQVK
Content-Disposition: form-data; name="_token"
P4wc9NVVZJe1VjalPwO6d6WQXZ9eEqPd84ICpToG
------WebKitFormBoundarySKMUFNO6dbgzeQVK
Content-Disposition: form-data; name="file"; filename="Screen Shot 2016-01-14 at 18.27.40.png"
Content-Type: image/png
------WebKitFormBoundarySKMUFNO6dbgzeQVK--
and When I look in the generated form THERE IS the csrf field
<input name="_token" type="hidden" value="P4wc9NVVZJe1VjalPwO6d6WQXZ9eEqPd84ICpToG">
Do you have any idea why it's not working even when I put crsf token where I should?
thank you for your time.
Simply place hidden field within your form like as
<input type="hidden" name="_token" value="{{csrf_token()}}">
You can make it different way by passing value of token using ajax call like as
$(function () {
$.ajaxSetup({
headers: { 'X-CSRF-TOKEN': $('meta[name="_token"]').attr('content') }
});
});
Instead of creating new element which is kinda dirty. You can just include it inside your manually init of dropzone.
var myDropzone = new Dropzone("#hello", {
url: $('#hello').attr('action'),
headers: {
'x-csrf-token': document.querySelectorAll('meta[name=csrf-token]')[0].getAttributeNode('content').value,
}
});
For more detailed integration with laravel dropzone you can refer to this tutorial Integrating Dropzone.js in Laravel 5 applications

Dropzone.js - How to add new property to file object after uploading file

I'm using dropzone and PHP to upload and delete files. When I load my upload page I create some mockfiles with the following params: name, size, thumbnail and id. This mock is set using pre uploaded data.
So when someone click on remove file button, I call the php method that delete the image.
My problem is when the user uploads an file and tries to delete it without loading the page. When it happens, dropzone file object just can't be altered.
I'm trying:
var dropZone3 = new Dropzone("#file3",{
init: function() {
this.on('success', function (file) {
console.log(file);
file['test'] = 'test';
file.test = 'test';
console.log(file);
})
},
paramName: 'file3',
autoProcessQueue:true,
uploadMultiple: false,
parallelUploads: 1,
maxFiles: 3,
maxFilesize: 5,
addRemoveLinks: true
My problem is that the first console.log and the second one inside init on success function shows me the same file.
Anyone knows how to fix it?
Thank you in advance.
It's possible to add properties directly to file object (dropzone v4.3.0)
var dropZone = new Dropzone(document.querySelector('.js-dropzone'), {
url: '/file/upload'
});
dropZone.on('success', function (file, response) {
var res = JSON.parse(response);
if (res.result == true) {
file.test = 'test';
file.id = res.id;
}
});
Don't think you can add a property to the file object when is already uploaded, but you can add it before on the accept property:
var dropZone3 = new Dropzone("#file3", {
url: "upload.php",
init: function () {
this.on('success', function (file) {
console.log(file);
})
},
accept: function(file, done) {
file.test = "test";
return done();
},
paramName: 'file3',
autoProcessQueue: true,
uploadMultiple: false,
parallelUploads: 1,
maxFiles: 3,
maxFilesize: 5,
addRemoveLinks: true
});

Categories

Resources