Не удается сохранить захваченное изображение с веб-камеры в Laravel 11 при использовании HTTPS

Вопрос или проблема

Я работаю над проектом под названием “Автоматическая система учета лиц”, которая будет распознавать лицо пользователя, отображать информацию о пользователе и сохранять захваченное изображение на локальном сервере.

Процесс выглядит так:
пользователь сканирует изображение с помощью веб-камеры -> система сопоставляет сканированное лицо пользователя с моделями -> получает данные пользователя с помощью JSON -> сохраняет захваченное изображение на сервере, используя JSON.

Проблема в том, что я включил SSL в Laragon и использую HTTPS для улучшения производительности моего проекта, и всё работает, кроме функции “сохранить захваченное изображение”. Но если я отключаю SSL и использую только HTTP, функция “сохранить захваченное изображение” работает нормально и сохраняет захваченные изображения в хранилище сервера.

Вот код:
js:

async function saveImageToServer(imageBlob, label) {
    const formData = new FormData();
    formData.append("image", imageBlob, "capturedImg.png");
    formData.append("label", label);

    try {
        const response = await fetch("/api/saveImage", {
            method: "POST",
            headers: {
                "CSRF-TOKEN": csrfToken,
            },
            body: formData,
        });

        if (response.ok) {
            const data = await response.json();
            if (data.imageUrl) {
                displayImageOnCanvas(data.imageUrl);
                console.log("Изображение сохранено и отображено на холсте");
            } else {
                console.error("Ответ не содержал imageUrl:", data);
            }
        } else {
            const errorData = await response.json();
            console.error("Не удалось сохранить изображение:", errorData);
        }
    } catch (error) {
        console.error("Ошибка при сохранении изображения:", error);
    }
}

контроллер

 public function storeImage(Request $request)
    {
        if ($request->hasFile('image') && $request->input('label')) {
            $timestamp = getCurrentDate();
            Session::put('current_date', $timestamp);

            $image = $request->file('image');
            $kodePegawai = $request->input('label');

            // Убедитесь, что каталог загрузки существует
            $uploadDir="labels/" . $kodePegawai . '/capturedImg/';
            Storage::disk('public')->makeDirectory($uploadDir);

            $imageName = $kodePegawai . $timestamp . '.png';

            $path = $image->storeAs($uploadDir, $imageName, 'public');

            if ($path) {
                $imageUrl = asset('storage/' . $uploadDir . $imageName);
                return response()->json(['imageUrl' => $imageUrl]);
            } else {
                return response()->json(['error' => 'Сервер не смог сохранить изображение'], 500);
            }
        } else {
            return response()->json(['error' => 'Изображение или метка не получены'], 400);
        }
    }

результат:

POST https://indodacin.test/api/saveImage 419
saveImageToServer @ script.js:261
(anonymous) @ script.js:197
setInterval
startFaceDetection @ script.js:142
await in startFaceDetection
(anonymous) @ script.js:59 Понять эту ошибку
script.js:282 Ошибка при сохранении изображения: SyntaxError: Unexpected token '<', "<!DOCTYPE "... недопустимый JSON

Я пробовал много решений из других тем, спрашивал у GPT, что не так, и ни одно из их решений не сработало. Вот что я пробовал:

  1. проверить и обновить права на хранилище
  2. проверить CSRF-токен
  3. использовать путь, который был указан в хранилище сервера и т. д.

Ответ или решение

Проблема, с которой вы столкнулись при попытке сохранить захваченное изображение с веб-камеры через HTTPS в Laravel 11, может быть связана с несколькими факторами. Давайте рассмотрим, вероятные причины и пути их решения.

1. Ошибка 419 – CSRF-токен

Ошибка 419 обычно указывает на проблему с проверкой CSRF-токена. При использовании HTTPS убедитесь, что вы правильно передаете CSRF-токен в заголовках запроса. Проверьте, правильно ли вы его получаете на клиенте.

Пример получения токена в JavaScript:

const csrfToken = document.querySelector('meta[name="csrf-token"]').getAttribute('content');

Убедитесь, что в вашем HTML-документе есть мета-тег:

<meta name="csrf-token" content="{{ csrf_token() }}">

2. Корректный путь

Следует убедиться, что вы используете правильный путь для отправки POST-запроса. Попробуйте использовать полный путь с учетом домена при вызове fetch().

3. Ответ сервера не в формате JSON

Ошибка Unexpected token '<', "<!DOCTYPE "... is not valid JSON говорит о том, что ответ от сервера не является корректным JSON. Это часто происходит, когда сервер возвращает HTML-документ (например, страницу ошибки). Проверьте, что происходит на стороне сервера, когда выполняется запрос.

Рекомендации:

  • Проверьте файл storage/logs/laravel.log на наличие ошибок, которые могут более подробно объяснить причину сбоя.
  • Используйте инструменты разработчика вашего браузера (например, вкладка "Сеть") для проверки, что именно возвращает сервер при выполнении запроса.

4. Настройки CORS

При работе с HTTPS важно убедиться, что ваши настройки CORS (Cross-Origin Resource Sharing) настроены правильно. Если ваш фронтенд и бэкенд находятся на разных поддоменах или портах, это может вызвать проблемы.

Пример настройки CORS в Laravel:

В файле app/Http/Middleware/HandleCors.php убедитесь, что указаны необходимые заголовки:

public function handle($request, Closure $next)
{
    return $next($request)
        ->header('Access-Control-Allow-Origin', '*')
        ->header('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE, OPTIONS')
        ->header('Access-Control-Allow-Headers', 'Content-Type, X-Auth-Token, Origin, Authorization, X-CSRF-TOKEN');
}

5. Проверьте права на папку хранения

Проблема также может заключаться в недостаточных правах на записи в директории storage. Убедитесь, что сервер имеет права на запись в эту папку:

chmod -R 775 storage

Или установите владельца на пользователя, под которым запущен ваш веб-сервер (например, www-data для Apache или Nginx):

chown -R www-data:www-data storage

Заключение

Пожалуйста, проверьте все предложенные рекомендации шаг за шагом. Это должно помочь вам выявить и решить проблему с сохранением изображений при использовании HTTPS в Laravel 11. Если ни один из этих шагов не помог, рассмотрите возможность тестирования проекта в локальной среде без SSL, а затем добавления HTTPS после того, как основная функциональность будет проверена и отлажена.

Оцените материал
Добавить комментарий

Капча загружается...