如何在Laravel 9中下载mime类型为application/octet-stream的文件?
Laravel 9中下载application/octet-stream类型文件的解决方案
问题根源
Laravel 9依赖的Flysystem库将application/octet-stream列入了INCONCLUSIVE_MIME_TYPES列表,导致Storage的download方法无法识别该类型,进而报错。旧版Laravel因为依赖的Flysystem版本较低,没有这个限制,所以能正常运行。
解决方法
方法一:手动指定MIME类型返回响应
绕过Storage的自动MIME检测逻辑,直接手动设置响应头返回文件:
方式1:用绝对路径直接返回
// 获取文件的绝对路径 $fileAbsolutePath = Storage::path($shippingLabelPrn); // 指定下载后的文件名 $downloadFileName = 'shipping_label.prn'; return response()->download( $fileAbsolutePath, $downloadFileName, [ 'Content-Type' => 'application/octet-stream', 'Content-Disposition' => "attachment; filename=\"{$downloadFileName}\"" ] );
方式2:读取文件内容后返回响应
$fileContent = Storage::get($shippingLabelPrn); $downloadFileName = 'shipping_label.prn'; return response($fileContent, 200) ->header('Content-Type', 'application/octet-stream') ->header('Content-Disposition', "attachment; filename=\"{$downloadFileName}\"");
方法二:自定义MIME检测器,移除octet-stream的限制
不直接修改vendor文件,通过自定义检测器替换Flysystem默认的检测逻辑:
- 创建自定义检测器类
namespace App\Services; use League\Flysystem\Local\FallbackMimeTypeDetector; class CustomMimeTypeDetector extends FallbackMimeTypeDetector { // 复制原常量,移除application/octet-stream protected const INCONCLUSIVE_MIME_TYPES = [ 'application/x-empty', 'inode/x-empty', ]; }
- 在
AppServiceProvider中替换默认适配器
use App\Services\CustomMimeTypeDetector; use League\Flysystem\Local\LocalFilesystemAdapter; use Illuminate\Support\Facades\Storage; public function boot() { Storage::extend('local', function ($app, $config) { $root = $config['root']; $adapter = new LocalFilesystemAdapter( $root, LOCK_EX, LocalFilesystemAdapter::DISALLOW_LINKS, new CustomMimeTypeDetector() // 使用自定义检测器 ); return new \Illuminate\Filesystem\FilesystemAdapter( new \League\Flysystem\Filesystem($adapter, $config), $adapter, $config ); }); }
之后就可以正常使用return Storage::download($shippingLabelPrn);了。
内容的提问来源于stack exchange,提问作者Shringiraj Dewangan
相关产品推荐
相关产品推荐

