可以使用 axios/fetch 在新窗口中打开页面以便从 api 视图下载 csv?

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

我有一个 Django 视图,它使用 StreamingHttpResponse 将大型数据集从 Rest api 下载到本地 .csv。这很好用;但是,当我尝试使用 [IsAuthenticated] Permissions_classes 标记添加身份验证时,URL(当然)将变得不可访问,而不在标头中包含有效的用户不记名令牌。

这是views.py中的相关代码:

import csv
from django.http import StreamingHttpResponse

class Echo:
    def write(self, value):
        return value

def streaming_csv_view(request):
    queryset = Emissions.objects.all().values_list('year', 'value')
    echo_buffer = Echo()
    csv_writer = csv.writer(echo_buffer)
    labels=[('Year', 'Value')]
    rows = (csv_writer.writerow(row) for row in chain(labels,queryset))

    response = StreamingHttpResponse(rows, content_type="text/csv")
    response["Content-Disposition"] = 'attachment; filename="Emissions.csv"'
    return response

我在代码中的其他地方实现了这一点,以进行更标准的 API 调用(即检索数据),但无法理解如何为我的 csv 下载工作,这需要用户访问该页面...我可以吗使用 fetch/axios 调用在新窗口中打开此页面以启动下载,然后在下载完成后关闭窗口?我很难找到以这种方式使用 axios 的示例

我觉得我错过了一些东西......任何帮助将不胜感激。

这是对端点的典型获取 GET 请求,该请求不起作用...

const fetchData = async() => {

        url = `link/api/export-emissions`

        try{
            const response = await fetch(url,{
                method:'GET',
                headers:{
                'Content-Type':'application/json',
                'Authorization':'Bearer ' + String(authTokens.access)
                }
            })


        }catch (e){
        console.log(e)
        }

        }
reactjs django database react-native frontend
1个回答
0
投票

我假设您的网址工作正常,但是您可以尝试使用您的网址和 axios 下载 csv 文件的方法。

axios
.get("--your-url---", {   // eg.https://picsum.photos/800/800 (no auth required)
responseType: "blob",
headers: {
  Authorization: `Bearer YOUR_TOKEN_HERE`, //add your token here
},
onDownloadProgress: function (progressEve) {
  console.log(
    ((progressEve.loaded / progressEve.total) * 100).toFixed() + "%"
  );
},
})
.then((object) => {
const url = URL.createObjectURL(object.data);
const anchor = document.createElement("a");
anchor.href = url;

anchor.download = "name_of_file.extension";  //add name and extension
anchor.style.display = "none";
document.body.appendChild(anchor);
anchor.click();
anchor.remove();
URL.revokeObjectURL(url);
})
.catch((error) => console.log(error));
© www.soinside.com 2019 - 2024. All rights reserved.