Ошибка CORS 500 при загрузке изображения TinyMCE для предполетного ответа

#javascript #php #apache #cors #tinymce

#javascript #php #apache #cors #tinymce

Вопрос:

Я использую TinyMCE и пытаюсь загрузить изображение.Моя HTML-страница обслуживается Django. Пожалуйста, смотрите ниже мой обработчик загрузки изображения (предоставленный TinyMCE)

 images_upload_handler: function (blobInfo, success, failure, progress) {
            var xhr, formData;

            xhr = new XMLHttpRequest();
            //xhr.withCredentials = true;
            xhr.open('POST', 'http://localhost/tiny_upload.php');
            xhr.setRequestHeader('x-requested-with', 'XMLHttpRequest')
            xhr.upload.onprogress = function (e) {
                progress(e.loaded / e.total * 100);
            };

            xhr.onload = function () {
                var json;

                if (xhr.status < 200 || xhr.status >= 300) {
                    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);
            };

            xhr.onerror = function () {
                failure('Image upload failed due to a XHR Transport error. Code: '   xhr.status  
                    ' Message:'   xhr.responseText);
            };

            formData = new FormData();
            formData.append('file', blobInfo.blob(), blobInfo.filename());
            xhr.send(formData);
        }
  

И мой загрузчик php находится ниже

 <?php
error_reporting(E_ERROR | E_WARNING | E_PARSE);
header('Access-Control-Allow-Origin: ' . $_SERVER['HTTP_ORIGIN']);
/***************************************************
 * Only these origins are allowed to upload images *
 ***************************************************/
$accepted_origins = array("http://localhost", "http://192.168.1.1", "http://127.0.0.1:8000", "http://127.0.0.1");

/*********************************************
 * Change this line to set the upload folder *
 *********************************************/
$imageFolder = "images/";
reset($_FILES);
$temp = current($_FILES);
header('CUS_MSG: hello');
if (is_uploaded_file($temp['tmp_name'])) {
    header('CUS_MSG1: hello');
    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;
        }
    }

    /*
    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);

    // 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' => $filetowrite));
} else {
    // Notify editor that the upload failed
    header("HTTP/1.1 500 Server Error");
}
?>
  

Проблема здесь в том, что предполетный запрос всегда завершается ошибкой 500. Однако я не получаю этого, когда запускаю то же самое в Chrome с --disable-web-security флагом

введите описание изображения здесь

Ошибка в консоли Chrome

Доступ к XMLHttpRequest по адресу ‘http://localhost/tiny_upload .php ‘from origin’http://127.0.0.1:8000 ‘ заблокирован политикой CORS: Ответ на предполетный запрос не проходит проверку контроля доступа: у него нет статуса HTTP ok.

Пожалуйста, помогите в этой проблеме. Это происходит на локальном сервере WAMP, а также на сервере Apache на компьютере Centos

Комментарии:

1. Я попытался добавить множество других заголовков также для Allow-Headers, Allow-Methods, Request-Headers, Request-Methods, установив значение как *. Безуспешно

2. В вашем php -коде я видел только одно место, где скрипт возвращает 500 -код. Это происходит, когда функция is_uploaded_file возвращает не true значение. Что именно делает эта функция?

3. is_uploaded_file проверяет, был ли файл отправлен через POST, одна вещь, которую я заметил в предполетном запросе (параметры метода запроса), он не отправляет файл и сначала ожидает ответа с заголовками CORS, после чего фактический POST-запрос отправляется вместе с файлом.

4. Да, это так. Прежде всего, ajax отправляет OPTIONS -запрос, чтобы убедиться, что ajax-запрос имеет разрешение на отправку запроса из разных источников. CORS-заголовки отправлены обратно в OPTIONS-request , и это в вашем коде, но OPTIONS не содержит файлов, и ваш if оператор переходит в else -ветку, которая возвращает 500 -код. Итак, попробуйте указать действие для запроса ‘OPTIONS’. Если скрипт получит ‘OPTIONS’, сделайте exit , например.

5. @Evgeniy Большое спасибо за это. Я попробую

Ответ №1:

Спасибо @Evgeniy за ответ в комментариях.

Я изменил содержимое файла php на приведенное ниже

 <?php
error_reporting(E_ERROR | E_WARNING | E_PARSE);
/***************************************************
 * Only these origins are allowed to upload images *
 ***************************************************/
$accepted_origins = array("http://localhost", "http://192.168.1.1", "http://127.0.0.1:8000", "http://127.0.0.1");

/*********************************************
 * Change this line to set the upload folder *
 *********************************************/

$method = $_SERVER['REQUEST_METHOD'];
if ($method == 'OPTIONS') {
    if (isset($_SERVER['HTTP_ORIGIN'])) {
        if (in_array($_SERVER['HTTP_ORIGIN'], $accepted_origins)) {
            header('Access-Control-Allow-Origin: ' . $_SERVER['HTTP_ORIGIN']);
            header("HTTP/1.1 200 OK");
            return;
        } else {
            header("HTTP/1.1 403 Origin Denied");
            return;
        }
    }
} elseif ($method == 'POST') {
    $imageFolder = "images/";
    reset($_FILES);
    $temp = current($_FILES);
    if (is_uploaded_file($temp['tmp_name'])) {
        header('CUS_MSG1: hello');
        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;
            }
        }

        /*
    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);

        // 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' => 'http://' . $_SERVER['SERVER_NAME'] . '/' . $filetowrite));
    } else {
        // Notify editor that the upload failed
        header("HTTP/1.1 500 Server Error");
    }
} else {
    // Notify editor that the upload failed
    header("HTTP/1.1 500 Server Error");
}
?>
  

и удален xhr.setRequestHeader('x-requested-with', 'XMLHttpRequest') из файла JS