TinyMCE upload image: Unexpected end of JSON input

  file-upload, javascript, laravel, tinymce, xml

please don’t close this. I need help.

I have js function for uploading image with tinymce, and route on backend:

tinymce.init({
    selector:'#{{ $elementId }}',
    content_css: "{{ asset('css/tiny.css') }}",
    width: '100%',
    height: 600,
    plugins: [
        'lists preview hr anchor pagebreak link image wordcount fullscreen directionality paste textpattern table code'
    ],
    extended_valid_elements: 'svg[*],defs[*],pattern[*],desc[*],metadata[*],g[*],mask[*],path[*],line[*],marker[*],rect[*],circle[*],ellipse[*],polygon[*],polyline[*],linearGradient[*],radialGradient[*],stop[*],image[*],view[*],text[*],textPath[*],title[*],tspan[*],glyph[*],symbol[*],switch[*],use[*]',
    toolbar: 'undo redo | styleselect | bold italic forecolor backcolor | alignleft aligncenter alignright alignjustify | image | bullist numlist outdent indent | link | table | code',
    file_picker_types: 'image media',
    images_file_types: 'jpeg,jpg,png,gif',
    a11y_advanced_options: true,
    default_link_target: '_blank',
    automatic_uploads: true,
    convert_urls: false,
    images_upload_handler: function (blobInfo, success, failure, progress) {
        let xhr, formData;

        xhr = new XMLHttpRequest();
        xhr.withCredentials = false;

        xhr.open('POST', '/upload-image');

        let token = document.getElementById("_token").value;
        xhr.setRequestHeader("X-CSRF-Token", token);
        xhr.onload = function() {
            let 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) {
        let input = document.createElement('input');
        input.setAttribute('type', 'file');
        input.setAttribute('accept', 'image/*');
        input.onchange = function() {
            let file = this.files[0];
            let id = 'blobid' + (new Date()).getTime();
            let blobCache = tinymce.activeEditor.editorUpload.blobCache;
            let blobInfo = blobCache.create(id, file);
            blobCache.add(blobInfo);
            cb(blobInfo.blobUri(), { title: file.name });
        };
        input.click();
    }
});

and in my controller for route /upload-image I have TinyMCE’s postAcceptor script but I’m not sure how should I adjust it to my needs:

public function uploadImageWithTiny()
{
    /***************************************************
     * Only these origins are allowed to upload images *
     ***************************************************/
    $accepted_origins = array("http://localhost", "http://192.168.1.1", "http://example.com");

    /*********************************************
     * Change this line to set the upload folder *
     *********************************************/
    $imageFolder = "public/img/";

    if (isset($_SERVER['HTTP_ORIGIN'])) {
        // same-origin requests won't set an origin. If the origin is set, it must be valid.
        if (in_array($_SERVER['HTTP_ORIGIN'], $accepted_origins)) {
            header('Access-Control-Allow-Origin: ' . $_SERVER['HTTP_ORIGIN']);
        } else {
            header("HTTP/1.1 403 Origin Denied");
            return;
        }
    }

    // Don't attempt to process the upload on an OPTIONS request
    if ($_SERVER['REQUEST_METHOD'] == 'OPTIONS') {
        header("Access-Control-Allow-Methods: POST, OPTIONS");
        return;
    }

    reset ($_FILES);
    $temp = current($_FILES);
    if (is_uploaded_file($temp['tmp_name'])){
        /*
          If your script needs to receive cookies, set images_upload_credentials : true in
          the configuration and enable the following two headers.
        */
        // header('Access-Control-Allow-Credentials: true');
        // header('P3P: CP="There is no P3P policy."');

        // Sanitize input
        if (preg_match("/([^wsd-_~,;:[]().])|([.]{2,})/", $temp['name'])) {
            header("HTTP/1.1 400 Invalid file name.");
            return;
        }

        // Verify extension
        if (!in_array(strtolower(pathinfo($temp['name'], PATHINFO_EXTENSION)), array("gif", "jpg", "png"))) {
            header("HTTP/1.1 400 Invalid extension.");
            return;
        }

        // Accept upload if there was no origin, or if it is an accepted origin
        $filetowrite = $imageFolder . $temp['name'];
        move_uploaded_file($temp['tmp_name'], $filetowrite);

        // Determine the base URL
        $protocol = isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] == 'on' ? "https://" : "http://";
        $baseurl = $protocol . $_SERVER["HTTP_HOST"] . rtrim(dirname($_SERVER['REQUEST_URI']), "/") . "/";

        // Respond to the successful upload with JSON.
        // Use a location key to specify the path to the saved image resource.
        // { location : '/your/uploaded/image/file'}
        echo json_encode(array('location' => $baseurl . $filetowrite));

    } else {
        // Notify editor that the upload failed
        header("HTTP/1.1 500 Server Error");
    }

}

also I’m getting the error in console : VM16752:1 Uncaught SyntaxError: Unexpected end of JSON input at JSON.parse (<anonymous>) at XMLHttpRequest.xhr.onload

in my console log for xhr.responseText I see that xhr.responseText is empty, so I’m assuming that is the error, but I’m not sure how to solve it. Also status for this request is 200, but something is missing. I’m stuck at this point and I would appreciate help!

How can I get location path from uploaded image?

Source: Laravel

Leave a Reply