在React中下载文件

7

我有一个使用Laravel创建的Restful API,这个API是这样的:

http://127.0.0.1:8000/api/file/pdf/{id}

以下是我用于下载的代码:

public function pdfDownload($id){
       $pdf = Cv::findOrfail($id);
       return Storage::download('public/pdf/'.$pdf->pdf);
    }

这段代码在Postman和浏览器中可以正常工作,并直接下载文件,但是在React.js中却无法正常工作:

这里放置需要翻译的代码
pdfDownload = (id) => {
        fetch(' http://127.0.0.1:8000/api/file/pdf/' + id, {
            method: 'get',
            headers: {
                Accept: 'application/octet-stream',
                'Content-Type': 'application/octet-stream'
            }
        }).then((res) => res.json());
    };

我将这个函数在按钮中这样调用:

<Button color="primary" onClick={() => this.pdfDownload(data.id)}>
                                            Download
                                        </Button>

这个ID是正确的,我确认过了。我的问题是,当点击这个按钮时,如何下载文件?谢谢。

1个回答

16

XHR调用无法触发文件下载,因为浏览器的处理方式。您需要使用类似以下的JavaScript代码自己模拟文件下载:

参考

const url = window.URL.createObjectURL(new Blob([response.data]));
const link = document.createElement('a');
link.href = url;
link.setAttribute('download', 'file.pdf');
document.body.appendChild(link);
link.click();

或者使用File Saver包,如果您不介意额外的依赖。

FileSaver Npm


谢谢,看起来很不错,但是我该如何使用link.setAttribute('download', 'file.pdf');?我怎样才能传递我的API文件而不是(file.pdf)? - Osama Mohammed
请遵循那个GIST。Api结果blob应该用于创建Blob。我只是在download属性中举了一个file.pdf的例子,您可以根据您的文件类型使用任何文件名。 - AjayK
@OsamaMohammed 您可以根据需要更改文件名和扩展名。例如,如果API返回了一个扩展名为'.xlsx'的文件,则必须相应地更改扩展名和文件名。例如:link.setAttribute('download','my_excel_file.xlsx'); - Kazi
有没有办法在不加载到浏览器中的情况下下载文件?@AjayK - Jug Patel

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接