我有一个Laravel控制器,从数据库或API等来源检索二进制图像数据,并将其作为响应返回:
class ExampleController extends Controller
{
// ...
public function testImage(Request $request)
{
// This is a binary string not a stream or file handle
$binaryImageData = $this->repository->getImage($request->query);
return response($binaryImageData);
}
}
然而,由于Laravel返回一个Content-Type头值' text/html',当我在浏览器中打开它时,二进制数据被呈现为html。
我不能保证我将访问到正确的图像数据的内容类型。
那么我该如何检测并返回正确的类型呢?
我认为这些方法可以帮助:
mb_detect_encoding
(检测字符编码)
$encoding = mb_detect_encoding($binaryImageData, mb_list_encodings(), true);
Symfony HttpFoundation 组件文件 UploadedFile:: getClientMimeType
(返回文件mime类型)
$mimetype = $binaryImageData->getClientMimeType();
使用内容类型($mimetype)的响应头示例:
return response(Storage::get($file->path))
->withHeaders([
'Content-disposition' => 'attachment; filename=' . $file->file_name,
'Access-Control-Expose-Headers' => 'Content-Disposition',
'Content-Type' => $file->mimetype,
]);
经过进一步的研究,我确定Laravel没有特定的方法来检测二进制字符串的mime类型。但是有一种通用的PHP方法:
function detectMimeType(string $input)
{
return (new finfo(FILEINFO_MIME_TYPE))->buffer($input);
}
Laravel目前有league/filesystem作为依赖项,而后者又有league/mime-type-detection,它为finfo提供了自己的基于类的包装器。我建议任何喜欢league/mime-type-detection
的人在他们的项目composer.json
文件中明确地要求它,以防Laravel将来放弃需求。