【问题标题】:TinyMCE and Laravel 5.3 TokenMismatchExceptionTinyMCE 和 Laravel 5.3 TokenMismatchException
【发布时间】:2017-09-29 10:38:17
【问题描述】:

我正在尝试在服务器端使用 Laravel 5.3 实现 TinyMCE 图像上传:

这是我的 TinyMCE JS,目前在刀片模板中:

<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>

我处理 TinyMCE 发出的 POST 请求的路线:

Route::post("/discussions/save_images/", 'Discussion\DiscussionController@saveImages');

我处理每次上传的操作:

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 抛出一个 TokenMismatchException。如何将 CSRF 令牌传递到 TinyMCE 发出的 POST 请求中?

我知道通常可以通过{{ csrf_token }} 在模板中访问此令牌,但我不确定有关 TinyMCE 的正确配置。

【问题讨论】:

    标签: php laravel-5 tinymce csrf tinymce-4


    【解决方案1】:

    使用 images_upload_handler 执行自定义处理程序并在请求标头中设置 X-CSRF-Token 有效。以下是完整的 JS 代码最终的样子:

    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();
            }
        });
    

    【讨论】:

      【解决方案2】:

      使用 jquery,您可以使用以下代码将 csrf 令牌添加到任何 xhr 请求:

        $.ajaxPrefilter(function (options, originalOptions, xhr) {
            var token = '{{ csrf_token() }}';
      
            if (token) {
                return xhr.setRequestHeader('X-CSRF-TOKEN', token);
            }
        });
      

      【讨论】:

      • 似乎是一个很好的解决方案,但没有添加标题。
      猜你喜欢
      • 2017-03-28
      • 2017-05-21
      • 2017-02-21
      • 1970-01-01
      • 2023-04-06
      • 2015-10-04
      • 2018-07-11
      • 2016-03-06
      相关资源
      最近更新 更多