Laravel:使用 JavaScript 下载 PDF 文件(axios)

问题描述 投票:0回答:1

我有一个问题。我尝试从 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(&#039;%PDF-1.3\n%\xFF\xFF\xFF\xFF\n...&#039;)
#1 C:\xampp\htdocs\test Laravel\testAuthSanctum\vendor\laravel\framework\src\Illuminate\Routing\Controller.php(54): App\Http\Controllers\FilesController-&gt;show(&#039;wy8NNSV9uAvL0NP...&#039;)
#2 C:\xampp\htdocs\test Laravel\testAuthSanctum\vendor\laravel\framework\src\Illuminate\Routing\ControllerDispatcher.php(43): Illuminate\Routing\Controller-&gt;callAction(&#039;show&#039;, Array)
#3 C:\xampp\htdocs\test Laravel\testAuthSanctum\vendor\laravel\framework\src\Illuminate\Routing\Route.php(260): Illuminate\Routing\ControllerDispatcher-&gt;dispatch(Object(Illuminate\Routing\Route), Object(App\Http\Controllers\FilesController), &#039;show&#039;)
#4 C:\xampp\htdocs\test Laravel\testAuthSanctum\vendor\laravel\framework\src\Illuminate\Routing\Route.php(205): Illuminate\Routing\Route-&gt;runController()
#5 C:\xampp\htdocs\test Laravel\testAuthSanctum\vendor\laravel\framework\src\Illuminate\Routing\Router.php(798): Illuminate\Routing\Route-&gt;run()
#6 C:\xampp\htdocs\test Laravel\testAuthSanctum\vendor\laravel\framework\src\Illuminate\Pipeline\Pipeline.php(141): Illuminate\Routing\Router-&gt;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-&gt;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-&gt;handle(Object(Illuminate\Http\Request), Object(Closure), &#039;admin&#039;)
#9 C:\xampp\htdocs\test Laravel\testAuthSanctum\vendor\laravel\framework\src\Illuminate\Routing\Middleware\SubstituteBindings.php(50): Illuminate\Pipeline\Pipeline-&gt;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-&gt;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-&gt;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-&gt;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-&gt;handleRequestUsingNamedLimiter(Object(Illuminate\Http\Request), Object(Closure), &#039;api&#039;, Object(Closure))
#14 C:\xampp\htdocs\test Laravel\testAuthSanctum\vendor\laravel\framework\src\Illuminate\Pipeline\Pipeline.php(180): Illuminate\Routing\Middleware\ThrottleRequests-&gt;handle(Object(Illuminate\Http\Request), Object(Closure), &#039;api&#039;)
#15 C:\xampp\htdocs\test Laravel\testAuthSanctum\vendor\laravel\framework\src\Illuminate\Auth\Middleware\Authenticate.php(45): Illuminate\Pipeline\Pipeline-&gt;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-&gt;handle(Object(Illuminate\Http\Request), Object(Closure), &#039;sanctum&#039;)
#17 C:\xampp\htdocs\test Laravel\testAuthSanctum\vendor\laravel\framework\src\Illuminate\Pipeline\Pipeline.php(116): Illuminate\Pipeline\Pipeline-&gt;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-&gt;then(Object(Closure))
#19 C:\xampp\htdocs\test Laravel\testAuthSanctum\vendor\laravel\framework\src\Illuminate\Routing\Router.php(776): Illuminate\Routing\Router-&gt;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-&gt;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-&gt;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-&gt;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-&gt;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-&gt;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-&gt;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-&gt;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-&gt;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-&gt;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-&gt;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-&gt;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-&gt;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-&gt;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-&gt;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-&gt;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-&gt;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-&gt;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-&gt;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-&gt;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-&gt;then(Object(Closure))
#40 C:\xampp\htdocs\test Laravel\testAuthSanctum\vendor\laravel\framework\src\Illuminate\Foundation\Http\Kernel.php(144): Illuminate\Foundation\Http\Kernel-&gt;sendRequestThroughRouter(Object(Illuminate\Http\Request))
#41 C:\xampp\htdocs\test Laravel\testAuthSanctum\public\index.php(52): Illuminate\Foundation\Http\Kernel-&gt;handle(Object(Illuminate\Http\Request))
#42 C:\xampp\htdocs\test Laravel\testAuthSanctum\vendor\laravel\framework\src\Illuminate\Foundation\resources\server.php(16): require_once(&#039;C:\\xampp\\htdocs...&#039;)
#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);
      });
};

请帮助我

reactjs laravel pdf download
1个回答
0
投票

问题可能出在后端或前端。

后端(Laravel 服务器端)

请注意,出于安全原因,如果内容与给定的不匹配,浏览器可能会阻止您的响应

Content-Type

因此在测试下载功能时,请确保您回复的文件是真实的PDF文件。

完成后,另外尝试以下操作:

if ( ! file_exists($myAbsoluteFilePath)) {
    abort(404);
}
return response()->download($myAbsoluteFilePath, basename($myAbsoluteFilePath), [
    'Content-Type' => 'application/pdf',
]);

前端(JavaScript端)

你的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

© www.soinside.com 2019 - 2024. All rights reserved.