繁体   English   中英

Laravel 9 和 Javascript:如何下载从 Storage::download() 返回的文件

[英]Laravel 9 and Javascript: how to download a file returned from Storage::download()

免责声明:在创建这个问题之前,我已经检查了这里这里这里,还检查了Laravel 文档。

语境

  • Laravel 9 全栈
  • 前端没有 JS 框架,这意味着我使用的是 vanilla JS
  • Storage 上的文件夹设置如下:
    • 贮存
      • 应用程序
        • 民众
          • 文件夹1
            • 文件夹1A
            • 文件夹1B
            • 文件夹1C
            • ETC
  • 每个folder1X中存储的文件都是.pdf格式,我不知道它的名字。
  • 没有文件夹是空的,也没有无效/损坏的文件。

问题

我有一个FileController.php来下载folder1X/目录中的文件。 下载方法如下:

public function downloadFileFromStorage(Request $request): mixed
{
    $dirpath = $request->dirpath; // dirpath = public/folder1/folder1X. 

    $files = Storage::allFiles($dirpath);

    return response()->download(storage_path('app\\' . $files[0]));
}

(注意:dirpath 由客户端在 axios 请求中发送,并且也是在先前的请求中从数据库中获取的)

我的 Javascript CLI 需要启用此文件的下载。 通过单击按钮启用下载。 该按钮调用downloadPDF(dirpath) ,其工作方式如下:

function downloadPDF(dirpath) {
    axios.post('/download-pdf-file', { dirpath })
        .then(
            success => {
                const url = success.data
                const a = document.createElement('a')
                a.download = 'file.pdf'
                a.href = url
                a.click()
            },
            error => {
                console.log(error.response)
            }
        )
}

但是,当我运行这个 function 时,我得到一个about:blank#blocked错误。

尝试

  • 将客户端上a HTML DOM 方法更改为window.open(url)
  • response()更改为Storage::download($files[0], 'file-name.pdf') ,为此我还尝试在客户端上使用Blob ,如下所示:
success => {
    const blob = new Blob([success.data], { type: 'application/pdf' })
    const fileURL = URL.createObjectURL(blob)
    window.openURL(fileURL)
},
  • 还将Blob a HTML DOM 方法混合;
  • 在连接到$files[0]之前将storage_path参数更改为/app/public/

更新

根据@BenGooding@cengsemihsahin的提示,我将文件更改为以下内容:

JS


// FileDownload is imported on a require() at the code beginning

function downloadPDF(dirpath) {
    axios({
        url: '/download-pdf-file',
        method: 'GET',
        responseType: 'blob',
        options: {
            body: { dirpath }
        }
    }).then(
        success => {
            FileDownload(success.data, 'nota-fiscal.pdf')
        }
    )
}

PHP:


public function downloadFileFromStorage(Request $request): mixed
{
    $dirpath = $request->dirpath; // dirpath = public/folder1/folder1X. 

    $files = Storage::allFiles($dirpath);
    return Storage::download($files[0], 'filename.pdf');
}

现在它下载了一个无法打开的损坏的 PDF。

终于找到问题了,就在这里:

axios({
    url: '/download-pdf-file',
    method: 'GET',
    responseType: 'blob',
    options: {            // here
        body: { dirpath } // here
    }
})

Laravel 的请求箭头运算符->无法获取通过options发送的 GET 正文(至少,不是$request->key方式; 在这里查看更多信息)因此让我下载了一个损坏的文件 - 它没有获取任何文件在 Laravel 上,因为它根本没有得到任何路径。

这是我附带的解决方案:

因为我想在除了folder1X处的1X之外不会改变的路径中获取一个文件,所以我正在处理获得的路径并将1X作为 GET 查询参数发送:

let folderNumber = dirpath.split('/')
folderNumber = folderNumber[folderNumber.length].replaceAll('/', '')

axios({
    url: '/download-pdf-file?folder=',
    method: 'GET',
    responseType: 'blob'
})

这样我就不会将整个路径传递给后端,并且可以使用$request->query()获取folderNumber

public function downloadFileFromStorage(Request $request): mixed
{
    $folderNumber = $request->query('folderNumber');
    $folderPath = '/public/folder1/folder' . $folderNumber . '/';
    $files = Storage::allFiles($folderPath);
        
    return Storage::download($files[0], 'file-name.pdf');
}

简而言之:

  • 要下载文件,请使用GET请求;
  • 要将 arguments 发送到GET请求,请使用查询参数并使用$request->query('keyname')获取它们(或找出另一种方法。祝你好运;);

暂无
暂无

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

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