mirror of
https://github.com/kuaifan/dootask.git
synced 2025-12-13 20:12:48 +00:00
perf: 修复iOS下载中文名乱码的问题
This commit is contained in:
parent
508aaef303
commit
9bc3e56c79
@ -1537,7 +1537,7 @@ class DialogController extends AbstractController
|
|||||||
}
|
}
|
||||||
//
|
//
|
||||||
$filePath = public_path($array['path']);
|
$filePath = public_path($array['path']);
|
||||||
return Base::streamDownload($filePath, $array['name']);
|
return Base::BinaryFileResponse($filePath, $array['name']);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@ -1819,7 +1819,7 @@ class ProjectController extends AbstractController
|
|||||||
}
|
}
|
||||||
//
|
//
|
||||||
$filePath = public_path($file->getRawOriginal('path'));
|
$filePath = public_path($file->getRawOriginal('path'));
|
||||||
return Base::streamDownload($filePath, $file->name);
|
return Base::BinaryFileResponse($filePath, $file->name);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@ -106,7 +106,7 @@ class FileContent extends AbstractModel
|
|||||||
* @param File $file
|
* @param File $file
|
||||||
* @param $content
|
* @param $content
|
||||||
* @param $download
|
* @param $download
|
||||||
* @return array|\Symfony\Component\HttpFoundation\StreamedResponse
|
* @return array|\Symfony\Component\HttpFoundation\BinaryFileResponse
|
||||||
*/
|
*/
|
||||||
public static function formatContent($file, $content, $download = false)
|
public static function formatContent($file, $content, $download = false)
|
||||||
{
|
{
|
||||||
@ -118,7 +118,7 @@ class FileContent extends AbstractModel
|
|||||||
} else {
|
} else {
|
||||||
$filePath = public_path($content['url']);
|
$filePath = public_path($content['url']);
|
||||||
}
|
}
|
||||||
return Base::streamDownload($filePath, $name);
|
return Base::BinaryFileResponse($filePath, $name);
|
||||||
}
|
}
|
||||||
if (empty($content)) {
|
if (empty($content)) {
|
||||||
$content = match ($file->type) {
|
$content = match ($file->type) {
|
||||||
@ -147,7 +147,7 @@ class FileContent extends AbstractModel
|
|||||||
if ($download) {
|
if ($download) {
|
||||||
$filePath = public_path($path);
|
$filePath = public_path($path);
|
||||||
if (isset($filePath)) {
|
if (isset($filePath)) {
|
||||||
return Base::streamDownload($filePath, $name);
|
return Base::BinaryFileResponse($filePath, $name);
|
||||||
} else {
|
} else {
|
||||||
abort(403, "This file not support download.");
|
abort(403, "This file not support download.");
|
||||||
}
|
}
|
||||||
|
|||||||
@ -2976,17 +2976,15 @@ class Base
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 流下载,解决没有后缀无法下载的问题
|
* BinaryFileResponse 下载文件
|
||||||
* @param $file
|
* @param File|\SplFileInfo|string $file 文件对象或路径
|
||||||
* @param $name
|
* @param string|null $name 下载文件名
|
||||||
* @return mixed
|
* @return \Symfony\Component\HttpFoundation\BinaryFileResponse
|
||||||
*/
|
*/
|
||||||
public static function streamDownload($file, $name = null)
|
public static function BinaryFileResponse($file, $name = null)
|
||||||
{
|
{
|
||||||
if ($name && !str_contains($name, '.')) {
|
try {
|
||||||
$name .= ".";
|
// 处理文件对象
|
||||||
}
|
|
||||||
//
|
|
||||||
if (!$file instanceof File) {
|
if (!$file instanceof File) {
|
||||||
if ($file instanceof \SplFileInfo) {
|
if ($file instanceof \SplFileInfo) {
|
||||||
$file = new File($file->getPathname());
|
$file = new File($file->getPathname());
|
||||||
@ -2994,27 +2992,54 @@ class Base
|
|||||||
$file = new File((string)$file);
|
$file = new File((string)$file);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!$file->isReadable()) {
|
|
||||||
throw new FileException('File must be readable.');
|
// 检查文件是否可读和存在
|
||||||
|
if (!$file->isReadable() || !$file->isFile()) {
|
||||||
|
throw new FileException('File must be readable and exist.');
|
||||||
}
|
}
|
||||||
// 大于100M直接下载
|
|
||||||
if ($file->getSize() > 100 * 1024 * 1024) {
|
// 处理文件名
|
||||||
return Response::download($file->getPathname(), $name);
|
if (empty($name)) {
|
||||||
|
$name = basename($file->getPathname());
|
||||||
|
} elseif (!str_contains($name, '.')) {
|
||||||
|
$name .= '.' . $file->getExtension();
|
||||||
}
|
}
|
||||||
//
|
|
||||||
$filePath = $file->getPathname();
|
// 文件名安全处理
|
||||||
return Response::stream(function () use ($filePath) {
|
$name = Base::cutStr($name, 180);
|
||||||
$fileStream = fopen($filePath, 'r');
|
$name = str_replace(['"', '<', '>', '|', '/', '\\', '?', ':'], '', $name);
|
||||||
while (!feof($fileStream)) {
|
|
||||||
echo fread($fileStream, 1024);
|
// IE 浏览器特殊处理
|
||||||
flush();
|
$encodedName = $name;
|
||||||
|
if (isset($_SERVER['HTTP_USER_AGENT']) && preg_match("/MSIE|Internet Explorer|Trident/i", $_SERVER['HTTP_USER_AGENT'])) {
|
||||||
|
$encodedName = rawurlencode($name);
|
||||||
}
|
}
|
||||||
fclose($fileStream);
|
|
||||||
}, 200, [
|
// 创建响应对象
|
||||||
'Content-Type' => 'application/octet-stream',
|
return new \Symfony\Component\HttpFoundation\BinaryFileResponse($file->getPathname(), 200, [
|
||||||
'Content-Disposition' => 'attachment; filename="'.$name.'"',
|
'Content-Type' => $file->getMimeType() ?: 'application/octet-stream',
|
||||||
'Content-Length' => $file->getSize(),
|
'Content-Disposition' => sprintf(
|
||||||
|
'attachment; filename="%s"; filename*=UTF-8\'\'%s',
|
||||||
|
$encodedName,
|
||||||
|
rawurlencode($name)
|
||||||
|
),
|
||||||
|
// 添加缓存控制和安全相关的头
|
||||||
|
'Cache-Control' => 'private, no-transform, no-store, must-revalidate',
|
||||||
|
'Pragma' => 'public',
|
||||||
|
'Expires' => '0',
|
||||||
|
'Accept-Ranges' => 'bytes', // 支持断点续传
|
||||||
|
'X-Content-Type-Options' => 'nosniff', // 安全相关
|
||||||
]);
|
]);
|
||||||
|
} catch (\Exception $e) {
|
||||||
|
\Log::error('File download failed', [
|
||||||
|
'error' => $e->getMessage(),
|
||||||
|
'file' => $file->getPathname() ?? null,
|
||||||
|
'name' => $name ?? null,
|
||||||
|
'user_agent' => $_SERVER['HTTP_USER_AGENT'] ?? null, // 添加更多调试信息
|
||||||
|
'ip' => request()->ip()
|
||||||
|
]);
|
||||||
|
abort(403, 'File download failed');
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user