Как преобразовать изображение base64 в UploadedFile Laravel - PullRequest
1 голос
/ 22 октября 2019

Vue Версия: 2.6.10

Laravel Версия: 6.0

Привет, ребята,

Я использую этот пакет загрузки Vue и все хорошо на стороне клиента (по крайней мере, я так думаю), но на стороне сервера, что я использую laravel, есть некоторые проблемы.

Вот мой метод отправки vue:

        setImage: function (file) {
            let formData = new FormData();
            formData.append('file', file);
            axios.post(upload_route, formData , {
                headers: { 'Content-Type': 'multipart/form-data' }
            })
                .then(response => {
                    // upload successful
                })
                .catch(error => console.log(error));
        },

И это мой метод на стороне сервера:

    public function upload(Request $request){
        $path = $request->file('file')->store('avatars');
        return response('upload success' , 200);
    }

И когда я загружаю файл на сервер, выдается эта ошибка:

"message": "Call to a member function store() on null",

И для записи объекта файлаЯ отправляю setImage Функция выглядит примерно так (если я регистрирую это с console.log):

data:image/jpeg;base64,/9j/4AAQSkZJRgABAQAAAQABAAD/2wBDAAEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQH/2wBDAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQE...

Спасибо.

Ответы [ 2 ]

2 голосов
/ 23 октября 2019

Я считаю, что file параметр на setImage не является File объектом. Таким образом, $request->file('file') - это null, потому что вы прикрепляете string (base64), а не файл.

Вы сказали нам, что вывод из console.log - это путь base64, тогда вам нужно преобразовать это(base64) в файл.

Поскольку вы используете Laravel, вот техника:

use Illuminate\Support\Str;
use Illuminate\Http\UploadedFile;
use Illuminate\Support\Facades\Storage;
use Symfony\Component\HttpFoundation\File\File;

.....

$base64File = $request->input('file');

// decode the base64 file
$fileData = base64_decode(preg_replace('#^data:image/\w+;base64,#i', '', $base64File));

// save it to temporary dir first.
$tmpFilePath = sys_get_temp_dir() . '/' . Str::uuid()->toString();
file_put_contents($tmpFilePath, $fileData);

// this just to help us get file info.
$tmpFile = new File($tmpFilePath);

$file = new UploadedFile(
    $tmpFile->getPathname(),
    $tmpFile->getFilename(),
    $tmpFile->getMimeType(),
    0,
    true // Mark it as test, since the file isn't from real HTTP POST.
);

$file->store('avatars');

Обновление

Поскольку выиспользуя vue-image-upload-resize , я проверяю документацию, встроенную в него, чтобы изменить вывод с base64 на blob, поэтому вы можете просто:

<image-uploader
    ...
    output-format="blob"
    ... />
0 голосов
/ 23 октября 2019
<?php
if (preg_match('/^data:image\/(\w+);base64,/', $data, $type)) {
    $data = substr($data, strpos($data, ',') + 1);
    $type = strtolower($type[1]); // jpg, png, gif
​
    if (!in_array($type, [ 'jpg', 'jpeg', 'gif', 'png' ])) {
        throw new \Exception('Image Type is Not valid');
    }
    $data = base64_decode($data);
    if ($data === false) {
        throw new \Exception('Failed to Decode BASE64');
    }
} else {
    throw new \Exception('Data Not Matched With Image Data');
}
file_put_contents("image_name.{$type}", $data);//save decoded data as image 
?>

Этот декодер и preg_match всегда работали для меня всякий раз, когда у меня есть изображение типа

data:image/jpeg;base64

Передайте эти данные как $ data, а тип вашего расширения как $ type

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...