TinyMCE and Laravel 5.3 TokenMismatchException
csrf, laravel-5, php, tinymce, tinymce-4
Solution
Doing a custom handler with images_upload_handler and setting the X-CSRF-Token in the request header worked. Here is what the complete JS code ended up looking like:
tinymce.init({
plugins: [
"advlist autolink lists link image charmap print preview hr anchor pagebreak",
"searchreplace wordcount visualblocks visualchars code fullscreen",
"insertdatetime media nonbreaking save table contextmenu directionality",
"emoticons template paste textcolor colorpicker textpattern"
],
selector: 'textarea',
images_upload_handler: function (blobInfo, success, failure) {
var xhr, formData;
xhr = new XMLHttpRequest();
xhr.withCredentials = false;
xhr.open('POST', '/discussions/save_images');
var token = document.getElementById("_token").value;
xhr.setRequestHeader("X-CSRF-Token", token);
xhr.onload = function() {
var json;
if (xhr.status != 200) {
failure('HTTP Error: ' + xhr.status);
return;
}
json = JSON.parse(xhr.responseText);
if (!json || typeof json.location != 'string') {
failure('Invalid JSON: ' + xhr.responseText);
return;
}
success(json.location);
};
formData = new FormData();
formData.append('file', blobInfo.blob(), blobInfo.filename());
xhr.send(formData);
},
file_picker_callback: function(cb, value, meta) {
var input = document.createElement('input');
input.setAttribute('type', 'file');
input.setAttribute('accept', 'image/*');
input.onchange = function() {
var file = this.files[0];
var id = 'blobid' + (new Date()).getTime();
var blobCache = tinymce.activeEditor.editorUpload.blobCache;
var blobInfo = blobCache.create(id, file);
blobCache.add(blobInfo);
cb(blobInfo.blobUri(), { title: file.name });
};
input.click();
}
});
Problem
I'm trying to implement TinyMCE image uploads, using Laravel 5.3 on the server side: here is my JS for TinyMCE, which is currently in a blade template: ``` <script src="{{ URL::to("/tinymce/tinymce.min.js") }}"></script> <script> tinymce.init({ selector: 'textarea', plugins: [ "advlist autolink lists link image charmap print preview hr anchor pagebreak", "searchreplace wordcount visualblocks visualchars code fullscreen", "insertdatetime media nonbreaking save table contextmenu directionality", "emoticons template paste textcolor colorpicker textpattern" ], toolbar: "insertfile undo redo | styleselect | bold italic | alignleft aligncenter alignright alignjustify | bullist numlist outdent indent | link image media", relative_urls: false, image_title: true, automatic_uploads: true, images_upload_url: '/discussions/save_images/', file_picker_types: 'image', images_upload_credentials: true, file_picker_callback: function(cb, value, meta) { var input = document.createElement('input'); input.setAttribute('type', 'file'); input.setAttribute('accept', 'image/*'); input.onchange = function() { var file = this.files[0]; var id = 'blobid' + (new Date()).getTime(); var blobCache = tinymce.activeEditor.editorUpload.blobCache; var blobInfo = blobCache.create(id, file); blobCache.add(blobInfo); cb(blobInfo.blobUri(), { title: file.name }); }; input.click(); } }); </script> ``` My route to handle the POST request made by TinyMCE: ``` Route::post("/discussions/save_images/", 'Discussion\DiscussionController@saveImages'); ``` My action to handle each upload: ``` public function saveImages(Request $request) { $filename = sha1(uniqid()).'.'.request()->file("name")->getClientOriginalExtension(); $request->file("name")->move('/images/discussions/', $filename); return json_encode(["location"=>"/images/discussions/".$filename]); } ``` Laravel throws a TokenMismatchException. How can I pass the CSRF token into the POST request that TinyMCE makes? I know that in general this token can be accessed in a template via `{{ csrf_token }}`, but I'm not sure about the correct configuration in regards to TinyMCE.