通过laravel后端将文件/二进制文件传递给laravel API

xj3cbfub  于 2023-04-07  发布在  其他
关注(0)|答案(1)|浏览(225)

从我的Vue前端,我上传了一个.glb文件到我的Laravel后端,文件到达那里很好,但是,我需要把它进一步传递到API,api把它作为二进制文件存储在数据库blob中。
这里有我尝试过的许多变体,而更多的方法已经被删除。起初,我试图发送文件本身,但后来我注意到原始的5 MB文件,在后端仍然是5 MB,在API上只有1B,所以它无法通过。然后我试图发布二进制数据本身,所以api不需要获取文件内容,只是将传入的数据存储到数据库中。我在后端从json_encode获取Malformed utf-8 characters,现在我在API端得到相同的错误。然后当幸运的是一些变体没有utf-8畸形错误时,我发现文件又回到了1B(空)。
后端代码:

public function uploadBinary(Request $r, $id)
{
    $file = $r->file('file');
    $bin = $file->get();
    // $bin = mb_convert_encoding($bin, 'UTF-8', 'auto');

    // $file->storePubliclyAs('', 'glbtest.glb');

    $res = Http::withToken(config('api.key'))
        ->acceptJson()
        ->withHeaders([
            // 'Content-Type' => 'model/gltf-binary'
            'Content-Type' => 'application/octet-stream'
        ])
        // ->withBody($bin, 'application/octet-stream')
        ->asMultipart()
        // ->attach('file', asset('glbtest.glb'))
        // ->post(replaceWildcards(config('api.urls.tdmodels.binary'), compact('id')));
        // ->post(replaceWildcards(config('api.urls.tdmodels.binary'), compact('id')), $bin);
        ->post(replaceWildcards(config('api.urls.tdmodels.binary'), compact('id')), [
            'file' => $bin
            // 'file' => file_get_contents(storage_path('app/glbtest.glb'))
        ]);

    return response()->json([
        'message' => 'uplo',
        'body' => $res->body(),
        'sizebe' => $file->getSize(),
        'pathbe' => $file->path(),
        'asset' => asset('glbtest.glb'),
    ]);
}

API代码:

public function uploadBinary($id, Request $request)
{
    // $request->setJson(null);
    $tdmodel = Tdmodel::findOrFail($id);

    // $binaryData = $request->getContent();
    // $file = $request->file('file');
    // $binaryData = $file->getContent();

    // $tdmodel->binary_file = $request->getContent();
    // $tdmodel->binary_file = $binaryData;
    $tdmodel->binary_file = $request->file;
    $tdmodel->save();

    return response()->json([
        'message' => 'Binary file uploaded successfully',
        // 'fileAPI' => $file->getSize()
    ]);
}

我可以发送文件本身,但我错过了一些东西吗?我可以在没有Laravel的Http尝试json编码和解码数据的情况下发送二进制文件吗?我觉得这个问题必须有一个简单的解决方案,但我已经花了两天的时间。谢谢。

编辑:

经过更多的测试,我得到了上传整个5 MB到API的版本,但仍然只有16 B上传到数据库。我还检查了我的my.ini,其中上限足够高,max_allowed_packet=512M
后端:

public function uploadBinary(Request $r, $id)
{
    $file = $r->file('file');
    $bin = $file->get();

    $res = Http::withToken(config('api.key'))
        ->acceptJson()
        ->withBody($bin, 'application/octet-stream')
        ->post(replaceWildcards(config('api.urls.tdmodels.binary'), compact('id')));

    return response()->json([
        'message' => 'uplo',
        'body' => $res->body(),
        'sizebe' => $file->getSize(),
    ]);
}

API:

public function uploadBinary($id, Request $request)
{
    $tdmodel = Tdmodel::findOrFail($id);

    $binaryData = $request->getContent();
    $stream = fopen('php://memory', 'r+');
    fwrite($stream, $binaryData);
    rewind($stream);

    $tdmodel->binary_file = $stream;
    $tdmodel->save();

    return response()->json([
        'message' => 'Binary file uploaded successfully',
        'binlen' => strlen($binaryData),
        'fstat' => fstat($stream),
    ]);

来自后端的sizebe具有值5224096,然后来自API响应binlen:5224096fstat\":{\"0\":12,\"1\":0,\"2\":33206,\"3\":1,\"4\":0,\"5\":0,\"6\":-1,\"7\":5224096,\"8\":0,\"9\":0,\"10\":0,\"11\":-1,\"12\":-1,\"dev\":12,\"ino\":0,\"mode\":33206,\"nlink\":1,\"uid\":0,\"gid\":0,\"rdev\":-1,\"size\":5224096,\"atime\":0,\"mtime\":0,\"ctime\":0,\"blksize\":-1,\"blocks\":-1}}
这意味着我终于得到正确的二进制大小在API端太,无论是在二进制请求内容和流我把它移动到.但在数据库中仍然只有这个:

5hcedyr0

5hcedyr01#

所以,我最终只是用guzzle和一切工作。3天的工作在垃圾箱。

public function uploadBinary(Request $r, $id)
{
    if (!$r->hasFile('file')) {
        return response()->json([
            'message' => 'Binary data not found'
        ], 404);
    }

    $file = $r->file('file');
    $binary = $file->get();

    $client = new Client();

    $headers = [
        'Authorization' => config('api.key_bearer'),
        'Content-Type' => 'application/octet-stream',
    ];
    
    $res = $client->request('POST', replaceWildcards(config('api.urls.tdmodels.binary'), compact('id')), [
        'headers' => $headers,
        'body' => $binary,
    ]);

    return response()->json([
        'message' => 'Uploaded successfully.',
    ]);
}

相关问题