无法通过 Vue.js(Axios 帖子)从 Laravel 后端下载文件(pdf)

Lar*_*all 3 laravel vue.js

我在 Vue 中有一个多步骤表单,一旦我收集了所有信息,我就会将结果发布到 Laravel 控制器。这是站点的经过身份验证的区域。我正在使用护照。所以基本上我有一个 Vue SPA,它是在 Laravel 5.7 框架内构建的网站的管理区域。

Vue file:
axios.post('/api/quotes/finalize', this.wizardModel)
                        .then(response => {
                            if (response.data.success) {
                                //
                            }
                        })
                        .catch(err => {
                            if (err.response.status == 401) {
                                window.location.href = '/login';
                            }
                            swal.showValidationError(
                                `Request failed: ${error}`
                            )

                        })
Run Code Online (Sandbox Code Playgroud)

控制器获取数据并制作 pdf。所有这些都在起作用。然后它需要查看三个操作 - 通过电子邮件发送 PDF、通过 CC 发送 PDF 以及下载 PDF。

    public function finalizeQuote(Request $request)
{
        $data = $request->all();
        $data['phone'] = $this->formatTelephone($data['phone']);

        $dateStamp = date('Ymdhis', strtotime('now'));
        $fileName = 'quote-' . $dateStamp . '.pdf';
        $html = View::make('quotes.quote', compact('data'))->render();

        $conv = new Converter();
        $conv->addPage($html)
            ->save('storage/' . $fileName);

        if ($data['actions']['emailPDF']) {
                $message = (new Proposal('storage/' . $fileName))
                                ->onConnection('redis')
                                ->onQueue('emails');

                if ($data['actions']['carbonCopy']) {
                    Mail::to($data['emailAddress'])
                        ->cc(Auth::user()->email)
                        ->queue($message);
                } else {
                    Mail::to($data['emailAddress'])->queue($message);
                }

            }

            if ($data['actions']['downloadPDF']) {
                return response()->download(public_path('storage/' . $fileName));
            }
}
Run Code Online (Sandbox Code Playgroud)

所以在开发工具中,我在响应中看到了 pdf 文件。浏览器中不会发生下载。我确定我只是在这里遗漏了一些基本的东西。

pid*_*zle 6

单独的 Ajax 请求无法调用下载。您可以有一个隐藏表单将您的数据发布到您的 api 端点,这可能是最快的解决方案。

Axios 有一种内置的方法可以轻松做到这一点

axios({
    method: 'post',
    url: '/api/quotes/finalize',
    data: wizardModelFormData,
    config: { headers: {'Content-Type': 'multipart/form-data' }}
    })
Run Code Online (Sandbox Code Playgroud)

您必须发送表单数据,而不是在请求中发送 json。设置表单数据对象非常容易,在 FormData 上快速搜索一下就足够了。

另一种方法是做这样的事情。让端点为您的文件返回下载 url,

   if ($data['actions']['downloadPDF']) {
        return response()->json(["download_url" => "/api/download/" . $fileName]);
    }
Run Code Online (Sandbox Code Playgroud)

在客户端,用于window.location将浏览器位置设置为仅返回文件的 api 端点(在本例中为 /api/download/{fileName})。然后浏览器将下载从您设置的该位置返回的任何文件(如果您正确设置了标题)。

这意味着您必须实现 /api/download/{fileName} 路由,但这就是您可以放置​​类似内容的地方。

return response()->download(public_path('storage/' . $fileName));
Run Code Online (Sandbox Code Playgroud)

显然,这只是一个简单的解释,不需要以完全相同的方式实现,但它可以传达这个想法。

现在,您需要确保没有将任何敏感文件放入 storage/ 并设置了一些权限。