简体   繁体   English

如何使用 javascript 从 API 下载内联 pdf?

[英]How to download an inline pdf received from API using javascript?

I have a backend which handles various actions with pdfs, one of them - combining multiple pdfs into a single one.我有一个后端可以处理带有 pdf 的各种操作,其中之一 - 将多个 pdf 合并为一个。

The scenario is as follows:场景如下:

  • User arranges multiple pdfs in a virtual list and gives this list a name.用户在一个虚拟列表中排列多个 pdf,并为该列表命名。
  • User clicks "download list" button.用户点击“下载列表”按钮。
  • Backend (Laravel) is called over API to merge the needed pdfs and returns a file response.通过 API 调用后端 (Laravel) 以合并所需的 pdf 并返回文件响应。 return response()->file(realpath($pathToFile), ['Content-Disposition' => 'inline; filename="'.$file,'Content-Type' => 'application/pdf']);

What I need to do is open this received file in a new window as inline pdf preview but I must have it named (I've tried using blobs but there's no option to provide a title) so that when user clicks on the "download" button of the pdf viewer, they get a named download, which is named by the list title.我需要做的是在新的 window 中打开这个收到的文件作为内联 pdf 预览,但我必须将它命名(我尝试使用 blob,但没有提供标题的选项),以便当用户点击“下载” pdf 查看器的按钮,他们得到一个命名下载,它由列表标题命名。 Sounds like a pretty basic task but I can't find any proper solutions on how to achieve this.听起来像是一项非常基本的任务,但我找不到任何适当的解决方案来实现这一目标。 Providing url to a file instead of a file response is also not an option because users are only allowed to download their lists and they should not be able to retrieve these files directly by url.将 url 提供给文件而不是文件响应也不是一种选择,因为用户只能下载他们的列表,并且他们不应该能够直接通过 url 检索这些文件。

I managed to solve my issue by a walkaround, which is probably not the most optimal solution and feels a bit hack-ish but that's the only solution that worked for me.我设法通过绕行解决了我的问题,这可能不是最优化的解决方案,而且感觉有点 hack-ish,但这是唯一对我有用的解决方案。

I created two routes on my API backend:我在我的 API 后端创建了两条路由:

1st route第一条路线

Route::post('/download-file', 'PdfProcessController@downloadFileApi'); Accepts file id as a parameter.接受文件id作为参数。 downloadFileApi method checks if user has access to the needed file, if they do, issue a token using Sanctum as so $token = Auth::user()->createToken('access_file_token'); downloadFileApi方法检查用户是否有权访问所需文件,如果有,则使用Sanctum发出令牌$token = Auth::user()->createToken('access_file_token'); lastly, this method returns url, which is a call to the second API route using the generated token return sprintf('%s/api/download-file/%s?_token=%s', env('APP_URL'), $request->input('id'), $token->plainTextToken);最后,此方法返回 url,这是使用生成的令牌调用第二个 API 路由return sprintf('%s/api/download-file/%s?_token=%s', env('APP_URL'), $request->input('id'), $token->plainTextToken);

2nd route Route::get('/download-file/{hash}', 'PdfProcessController@downloadFile')->middleware(['token.to.header', 'auth:sanctum']);第二条路线Route::get('/download-file/{hash}', 'PdfProcessController@downloadFile')->middleware(['token.to.header', 'auth:sanctum']); The token.to.header middleware is implemented based on this answer Autheticate via Laravel Sanctum by passing token as a GET query parameter Inside downloadFile token is destroyed (because it has been used) and an inline pdf is returned. token.to.header中间件是基于此答案实现的。 通过 Laravel Sanctum 进行身份验证,通过将令牌作为 GET 查询参数传递内部downloadFile令牌被破坏(因为它已被使用)并返回内联 Z43700941ED 。

On my front-end I do在我的前端我做

this.$axios.post('/api/download-file', {id: fileid})
.then(response => {
  window.open(response.data, '_blank');
})

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM