【问题标题】:How to convert base64 image to UploadedFile Laravel如何将 base64 图像转换为 UploadedFile Laravel
【发布时间】:2020-02-18 21:50:33
【问题描述】:

Vue 版本:2.6.10

Laravel 版本:6.0

我正在使用这个vue upload package,客户端一切正常(至少我是这么认为的)。但是在我使用 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": "调用成员函数 store() on null",

我在setImage 函数中发送的文件对象是这样的(如果我使用console.log 记录它):

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

【问题讨论】:

  • 我想你正在使用 vuex,你的 axios 调用是否链接了 vuex?
  • @jalil 不,我不使用 vuex,我只想直接上传它们。

标签: laravel vue.js


【解决方案1】:

我相信setImage 上的file 参数不是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"
    ... />

【讨论】:

  • 谢谢,我这样做了,它说:Impossible to create the root directory \"C:\\Users\\Mehdi\\Desktop\\rahyab\\storage\\app\\C:/Users/Mehdi/AppData/Local/Temp\".
  • @meti 哦,好吧,对不起,我忘记了。我已经更新了答案。再试一次。
  • @meti 我已经更新了我的答案,让您的生活更轻松。您只是不阅读文档。所以你可以使用你的原始代码。
  • 谢谢兄弟,我总是遇到 ajax 上传问题。谢谢。
【解决方案2】:
<?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 传递

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-11-03
    • 1970-01-01
    • 1970-01-01
    • 2015-12-09
    • 2013-12-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多