我有一个问题。我尝试从 Laravel 本地存储下载文件。当我发送请求时,出现错误 500。
API.php
Route::middleware(['auth:sanctum', 'ability:admin'])->group(function () {
Route::resource('files', FilesController::class);
});
我来自其余文件的请求(REST CLIENT vsCode Extension)
GET http://localhost:8000/api/files/wy8NNSV9uAvL0NPYydw5iaZDkz5XQYeFo2A7VZo0.pdf HTTP/1.1
responseType: "blob"
Authorization: Bearer 63|0EyovJatWTlWUX6f2RvfQ228QGlbdZVA5Ldn35FH
Accept: "application/pdf"
Content-Type: "application/pdf"
如果我发送上述请求,我会收到错误 500
HTTP/1.1 500 Internal Server Error
Host: localhost:8000
Date: Mon, 27 Mar 2023 17:08:09 GMT, Mon, 27 Mar 2023 17:08:09 GMT
Connection: close
X-Powered-By: PHP/8.1.10
Cache-Control: no-cache, private
Content-Type: text/html; charset=UTF-8
X-RateLimit-Limit: 60
X-RateLimit-Remaining: 57
Access-Control-Allow-Origin: *
<!DOCTYPE html>
<html lang="en" class="auto">
<!--
ValueError: file_get_contents(): Argument #1 ($filename) must not contain any null bytes in file C:\xampp\htdocs\test Laravel\testAuthSanctum\app\Http\Controllers\FilesController.php on line 106
#0 C:\xampp\htdocs\test Laravel\testAuthSanctum\app\Http\Controllers\FilesController.php(106): file_get_contents('%PDF-1.3\n%\xFF\xFF\xFF\xFF\n...')
#1 C:\xampp\htdocs\test Laravel\testAuthSanctum\vendor\laravel\framework\src\Illuminate\Routing\Controller.php(54): App\Http\Controllers\FilesController->show('wy8NNSV9uAvL0NP...')
#2 C:\xampp\htdocs\test Laravel\testAuthSanctum\vendor\laravel\framework\src\Illuminate\Routing\ControllerDispatcher.php(43): Illuminate\Routing\Controller->callAction('show', Array)
#3 C:\xampp\htdocs\test Laravel\testAuthSanctum\vendor\laravel\framework\src\Illuminate\Routing\Route.php(260): Illuminate\Routing\ControllerDispatcher->dispatch(Object(Illuminate\Routing\Route), Object(App\Http\Controllers\FilesController), 'show')
#4 C:\xampp\htdocs\test Laravel\testAuthSanctum\vendor\laravel\framework\src\Illuminate\Routing\Route.php(205): Illuminate\Routing\Route->runController()
#5 C:\xampp\htdocs\test Laravel\testAuthSanctum\vendor\laravel\framework\src\Illuminate\Routing\Router.php(798): Illuminate\Routing\Route->run()
#6 C:\xampp\htdocs\test Laravel\testAuthSanctum\vendor\laravel\framework\src\Illuminate\Pipeline\Pipeline.php(141): Illuminate\Routing\Router->Illuminate\Routing\{closure}(Object(Illuminate\Http\Request))
#7 C:\xampp\htdocs\test Laravel\testAuthSanctum\vendor\laravel\sanctum\src\Http\Middleware\CheckForAnyAbility.php(28): Illuminate\Pipeline\Pipeline->Illuminate\Pipeline\{closure}(Object(Illuminate\Http\Request))
#8 C:\xampp\htdocs\test Laravel\testAuthSanctum\vendor\laravel\framework\src\Illuminate\Pipeline\Pipeline.php(180): Laravel\Sanctum\Http\Middleware\CheckForAnyAbility->handle(Object(Illuminate\Http\Request), Object(Closure), 'admin')
#9 C:\xampp\htdocs\test Laravel\testAuthSanctum\vendor\laravel\framework\src\Illuminate\Routing\Middleware\SubstituteBindings.php(50): Illuminate\Pipeline\Pipeline->Illuminate\Pipeline\{closure}(Object(Illuminate\Http\Request))
#10 C:\xampp\htdocs\test Laravel\testAuthSanctum\vendor\laravel\framework\src\Illuminate\Pipeline\Pipeline.php(180): Illuminate\Routing\Middleware\SubstituteBindings->handle(Object(Illuminate\Http\Request), Object(Closure))
#11 C:\xampp\htdocs\test Laravel\testAuthSanctum\vendor\laravel\framework\src\Illuminate\Routing\Middleware\ThrottleRequests.php(126): Illuminate\Pipeline\Pipeline->Illuminate\Pipeline\{closure}(Object(Illuminate\Http\Request))
#12 C:\xampp\htdocs\test Laravel\testAuthSanctum\vendor\laravel\framework\src\Illuminate\Routing\Middleware\ThrottleRequests.php(102): Illuminate\Routing\Middleware\ThrottleRequests->handleRequest(Object(Illuminate\Http\Request), Object(Closure), Array)
#13 C:\xampp\htdocs\test Laravel\testAuthSanctum\vendor\laravel\framework\src\Illuminate\Routing\Middleware\ThrottleRequests.php(54): Illuminate\Routing\Middleware\ThrottleRequests->handleRequestUsingNamedLimiter(Object(Illuminate\Http\Request), Object(Closure), 'api', Object(Closure))
#14 C:\xampp\htdocs\test Laravel\testAuthSanctum\vendor\laravel\framework\src\Illuminate\Pipeline\Pipeline.php(180): Illuminate\Routing\Middleware\ThrottleRequests->handle(Object(Illuminate\Http\Request), Object(Closure), 'api')
#15 C:\xampp\htdocs\test Laravel\testAuthSanctum\vendor\laravel\framework\src\Illuminate\Auth\Middleware\Authenticate.php(45): Illuminate\Pipeline\Pipeline->Illuminate\Pipeline\{closure}(Object(Illuminate\Http\Request))
#16 C:\xampp\htdocs\test Laravel\testAuthSanctum\vendor\laravel\framework\src\Illuminate\Pipeline\Pipeline.php(180): Illuminate\Auth\Middleware\Authenticate->handle(Object(Illuminate\Http\Request), Object(Closure), 'sanctum')
#17 C:\xampp\htdocs\test Laravel\testAuthSanctum\vendor\laravel\framework\src\Illuminate\Pipeline\Pipeline.php(116): Illuminate\Pipeline\Pipeline->Illuminate\Pipeline\{closure}(Object(Illuminate\Http\Request))
#18 C:\xampp\htdocs\test Laravel\testAuthSanctum\vendor\laravel\framework\src\Illuminate\Routing\Router.php(799): Illuminate\Pipeline\Pipeline->then(Object(Closure))
#19 C:\xampp\htdocs\test Laravel\testAuthSanctum\vendor\laravel\framework\src\Illuminate\Routing\Router.php(776): Illuminate\Routing\Router->runRouteWithinStack(Object(Illuminate\Routing\Route), Object(Illuminate\Http\Request))
#20 C:\xampp\htdocs\test Laravel\testAuthSanctum\vendor\laravel\framework\src\Illuminate\Routing\Router.php(740): Illuminate\Routing\Router->runRoute(Object(Illuminate\Http\Request), Object(Illuminate\Routing\Route))
#21 C:\xampp\htdocs\test Laravel\testAuthSanctum\vendor\laravel\framework\src\Illuminate\Routing\Router.php(729): Illuminate\Routing\Router->dispatchToRoute(Object(Illuminate\Http\Request))
#22 C:\xampp\htdocs\test Laravel\testAuthSanctum\vendor\laravel\framework\src\Illuminate\Foundation\Http\Kernel.php(200): Illuminate\Routing\Router->dispatch(Object(Illuminate\Http\Request))
#23 C:\xampp\htdocs\test Laravel\testAuthSanctum\vendor\laravel\framework\src\Illuminate\Pipeline\Pipeline.php(141): Illuminate\Foundation\Http\Kernel->Illuminate\Foundation\Http\{closure}(Object(Illuminate\Http\Request))
#24 C:\xampp\htdocs\test Laravel\testAuthSanctum\vendor\laravel\framework\src\Illuminate\Foundation\Http\Middleware\TransformsRequest.php(21): Illuminate\Pipeline\Pipeline->Illuminate\Pipeline\{closure}(Object(Illuminate\Http\Request))
#25 C:\xampp\htdocs\test Laravel\testAuthSanctum\vendor\laravel\framework\src\Illuminate\Foundation\Http\Middleware\ConvertEmptyStringsToNull.php(31): Illuminate\Foundation\Http\Middleware\TransformsRequest->handle(Object(Illuminate\Http\Request), Object(Closure))
#26 C:\xampp\htdocs\test Laravel\testAuthSanctum\vendor\laravel\framework\src\Illuminate\Pipeline\Pipeline.php(180): Illuminate\Foundation\Http\Middleware\ConvertEmptyStringsToNull->handle(Object(Illuminate\Http\Request), Object(Closure))
#27 C:\xampp\htdocs\test Laravel\testAuthSanctum\vendor\laravel\framework\src\Illuminate\Foundation\Http\Middleware\TransformsRequest.php(21): Illuminate\Pipeline\Pipeline->Illuminate\Pipeline\{closure}(Object(Illuminate\Http\Request))
#28 C:\xampp\htdocs\test Laravel\testAuthSanctum\vendor\laravel\framework\src\Illuminate\Foundation\Http\Middleware\TrimStrings.php(40): Illuminate\Foundation\Http\Middleware\TransformsRequest->handle(Object(Illuminate\Http\Request), Object(Closure))
#29 C:\xampp\htdocs\test Laravel\testAuthSanctum\vendor\laravel\framework\src\Illuminate\Pipeline\Pipeline.php(180): Illuminate\Foundation\Http\Middleware\TrimStrings->handle(Object(Illuminate\Http\Request), Object(Closure))
#30 C:\xampp\htdocs\test Laravel\testAuthSanctum\vendor\laravel\framework\src\Illuminate\Foundation\Http\Middleware\ValidatePostSize.php(27): Illuminate\Pipeline\Pipeline->Illuminate\Pipeline\{closure}(Object(Illuminate\Http\Request))
#31 C:\xampp\htdocs\test Laravel\testAuthSanctum\vendor\laravel\framework\src\Illuminate\Pipeline\Pipeline.php(180): Illuminate\Foundation\Http\Middleware\ValidatePostSize->handle(Object(Illuminate\Http\Request), Object(Closure))
#32 C:\xampp\htdocs\test Laravel\testAuthSanctum\vendor\laravel\framework\src\Illuminate\Foundation\Http\Middleware\PreventRequestsDuringMaintenance.php(86): Illuminate\Pipeline\Pipeline->Illuminate\Pipeline\{closure}(Object(Illuminate\Http\Request))
#33 C:\xampp\htdocs\test Laravel\testAuthSanctum\vendor\laravel\framework\src\Illuminate\Pipeline\Pipeline.php(180): Illuminate\Foundation\Http\Middleware\PreventRequestsDuringMaintenance->handle(Object(Illuminate\Http\Request), Object(Closure))
#34 C:\xampp\htdocs\test Laravel\testAuthSanctum\vendor\laravel\framework\src\Illuminate\Http\Middleware\HandleCors.php(62): Illuminate\Pipeline\Pipeline->Illuminate\Pipeline\{closure}(Object(Illuminate\Http\Request))
#35 C:\xampp\htdocs\test Laravel\testAuthSanctum\vendor\laravel\framework\src\Illuminate\Pipeline\Pipeline.php(180): Illuminate\Http\Middleware\HandleCors->handle(Object(Illuminate\Http\Request), Object(Closure))
#36 C:\xampp\htdocs\test Laravel\testAuthSanctum\vendor\laravel\framework\src\Illuminate\Http\Middleware\TrustProxies.php(39): Illuminate\Pipeline\Pipeline->Illuminate\Pipeline\{closure}(Object(Illuminate\Http\Request))
#37 C:\xampp\htdocs\test Laravel\testAuthSanctum\vendor\laravel\framework\src\Illuminate\Pipeline\Pipeline.php(180): Illuminate\Http\Middleware\TrustProxies->handle(Object(Illuminate\Http\Request), Object(Closure))
#38 C:\xampp\htdocs\test Laravel\testAuthSanctum\vendor\laravel\framework\src\Illuminate\Pipeline\Pipeline.php(116): Illuminate\Pipeline\Pipeline->Illuminate\Pipeline\{closure}(Object(Illuminate\Http\Request))
#39 C:\xampp\htdocs\test Laravel\testAuthSanctum\vendor\laravel\framework\src\Illuminate\Foundation\Http\Kernel.php(175): Illuminate\Pipeline\Pipeline->then(Object(Closure))
#40 C:\xampp\htdocs\test Laravel\testAuthSanctum\vendor\laravel\framework\src\Illuminate\Foundation\Http\Kernel.php(144): Illuminate\Foundation\Http\Kernel->sendRequestThroughRouter(Object(Illuminate\Http\Request))
#41 C:\xampp\htdocs\test Laravel\testAuthSanctum\public\index.php(52): Illuminate\Foundation\Http\Kernel->handle(Object(Illuminate\Http\Request))
#42 C:\xampp\htdocs\test Laravel\testAuthSanctum\vendor\laravel\framework\src\Illuminate\Foundation\resources\server.php(16): require_once('C:\\xampp\\htdocs...')
#43 {main}
如果我从 React 发送请求,我也会收到错误 500
FilesController.php
public function show(string $filename)
{
if(Storage::disk('public')->exists("files/".$filename))
{
$path = Storage::disk('public')->get("files/".$filename);
$content = file_get_contents($path);
return response($content)->withHeaders([
'Content-Type' => mime_content_type($path),
'Accept' => "application/pdf",
'Content-Disposition' => 'attachment; filename="' . $filename . '"'
]);
}
abort(404);
}
授权工作完美。令牌是正确的。如果我尝试将
wy8NNSV9uAvL0NPYydw5iaZDkz5XQYeFo2A7VZo0.pdf
更改为无效文件名(不存在),则会出现 404 错误,因为条件语句将不会执行
如果我将显示方法更改为:
public function show(string $filename)
{
if (Storage::disk('public')->exists("files/".$filename)) {
return Storage::download('public/files/' . $filename, $filename, [
'Content-Type' => 'application/pdf',
'Content-Disposition' => 'attachment; filename="' . $filename . '"',
]);
}
}
react下载它,因为pdf文件是空白的。
axios方法
const getFile = (filename) => { //filename = "wy8NNSV9uAvL0NPYydw5iaZDkz5XQYeFo2A7VZo0.pdf"
axios.get(
"http://localhost:8000/api/files/" + filename,
{
headers: {
Authorization: "Bearer " + localStorage.getItem("token"),
responseType: "blob",
Accept: "application/pdf",
"Content-Type": "application/pdf"
},
}
)
.then((res) => {
const file = new Blob([res.data], { type: "application/pdf" });
const fileURL = URL.createObjectURL(file);
window.open(fileURL);
})
.catch((err) => {
console.log(err);
});
};
请帮助我
问题可能出在后端或前端。
请注意,出于安全原因,如果内容与给定的不匹配,浏览器可能会阻止您的响应
Content-Type
。
因此在测试下载功能时,请确保您回复的文件是真实的PDF文件。
完成后,另外尝试以下操作:
if ( ! file_exists($myAbsoluteFilePath)) {
abort(404);
}
return response()->download($myAbsoluteFilePath, basename($myAbsoluteFilePath), [
'Content-Type' => 'application/pdf',
]);
你的JS可能是错误的,尝试一下:
axios.get(
"http://localhost:8000/api/files/" + filename,
{
Authorization: "Bearer " + localStorage.getItem("token"),
responseType: 'arraybuffer'
}
).then((response) => {
// Parses file, and creates proxy (local data-URL for file).
var proxy = window.URL.createObjectURL(
new Blob([response.data], {type: "application/pdf"})
);
// Download from proxy.
var link = document.createElement('a');
document.body.appendChild(link); // Maybe required by Fire-fox browsers.
link.href = proxy;
link.download = "my-file.pdf";
link.click();
// Cleanup.
window.URL.revokeObjectURL(proxy);
link.remove();
});
或者:
axios({
method: 'get',
url: "http://localhost:8000/api/files/" + filename,
headers: {
Authorization: "Bearer " + localStorage.getItem("token"),
responseType: 'arraybuffer',
}
}).then((response) => {
// ... Same as above.
});
注意
是responseType
。arraybuffer