Laravel后端向Laravel API传递GLB二进制文件异常求助
问题:GLB文件经Laravel后端转递至API后无法正确存入Blob字段
我通过Vue前端以POST请求上传.glb文件到Laravel后端,后端能正常接收文件,但需要将其转递给另一个Laravel API,并以二进制形式存入数据库的Blob字段。尝试多种方法均未成功:
- 最初直接传递文件本身,后端接收的5MB文件到API后仅剩1B
- 尝试传递二进制数据,后端执行
json_encode时出现「Malformed utf-8 characters」错误,后续该错误转移至API端 - 偶尔无编码错误时,文件又会变成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编码解码来传递二进制数据?我觉得应该有简单的解决方案,但已经折腾两天了,求帮忙。
补充测试结果
经过更多测试,现在已经能将完整的5MB文件上传至API,但数据库中仍仅存入16B的数据。已检查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为5224096,fstat中的size也为5224096,说明API端已获取到完整的二进制数据,但数据库的Blob字段中仅存入16B的数据(截图显示字段内容为类似Resource id #xxx的资源标识符)。
内容的提问来源于stack exchange,提问作者narrei
相关产品推荐
相关产品推荐

