在函数中获取 blob 下载状态

Posted

技术标签:

【中文标题】在函数中获取 blob 下载状态【英文标题】:Fetch blob downloaded status in a function 【发布时间】:2021-06-15 06:58:26 【问题描述】:

根据 React 前端的请求,我正在服务器 NodeJS 端生成一个 excel 文件。我可以使用什么 - 某种类型的事件或承诺来验证 blob 下载过程是否完成?在文件下载时,我需要此状态来设置 Button 元素加载状态。

React 客户端函数:

export const download = (url, filename) => 
    fetch(url, 
        mode: 'no-cors' 
        /*
        * ALTERNATIVE MODE 
        mode: 'cors'
        
        *
        */
    ).then((transfer) => 
        return transfer.blob();                // RETURN DATA TRANSFERED AS BLOB
    ).then((bytes) => 
        let elm = document.createElement('a');  // CREATE A LINK ELEMENT IN DOM
        elm.href = URL.createObjectURL(bytes);  // SET LINK ELEMENTS CONTENTS
        elm.setAttribute('download', filename); // SET ELEMENT CREATED 'ATTRIBUTE' TO DOWNLOAD, FILENAME PARAM AUTOMATICALLY
        elm.click();                             // TRIGGER ELEMENT TO DOWNLOAD
        elm.remove();
    ).catch((error) => 
        console.log(error);                     // OUTPUT ERRORS, SUCH AS CORS WHEN TESTING NON LOCALLY
    )

我试过了:

要在 .then(bytes) 块中返回 false,要使用异步,await in fetch。只有我得到的结果是 console.log ,其中 .then(bytes) 块给出了正确的同步:

 ).then((bytes) => 
            console.log("Downloaded, working");
            let elm = document.createElement('a');  // CREATE A LINK ELEMENT IN DOM
            elm.href = URL.createObjectURL(bytes);  // SET LINK ELEMENTS CONTENTS

其他方式立即设置变量(我知道是因为承诺),所以按钮旋转与下载过程(3 秒)不同步(1 秒)。有没有其他办法?

初始客户端请求:

fetch('/api/hrreportdetailed', 
                method: 'POST',
                headers: 
                    'Content-Type': 'application/json'
                ,
                body: JSON.stringify(
                state
                )
            );
            download('/api/hrreportdetailed',"Report "+getDDMMYYY(new Date())+".xlsx");
            setBtnLoad2(variable);

【问题讨论】:

你的问题很不清楚。你能请周围的人重新制定一下吗?也就是说,不清楚您是否只想知道下载何时完成,或者您是否想要下载时的一种进度事件。 Ps:我希望它是***.com/questions/47285198/…的骗子,但也许只是对fetch()的第一个Promise做出反应可能就足够了(浏览器实际上是在fetch().then()response.[consume]().then()之间下载) @Kaiido 我只需要这个函数来等待(生成 excel 文件时的实时时间)适当的时间(3 秒而不是 1),所以我可以使用 setBtnLoad2(variable) 作为 true微调器组件中的 /false 指示器。 那么,fetch( url ).then( (resp) => is_downloading = true; return resp.blob(); ).then( (blob) => is_downloading = false; ... ) 就足够了。 【参考方案1】:

我重新制作了这个函数,现在它可以按预期工作了:

export const download = async (url, filename) => 
    let response = await fetch(url, 
        mode: 'no-cors' 
        /*
        * ALTERNATIVE MODE 
        mode: 'cors'
        
        *
        */  
    ); 
    try 
        let data = await response.blob();
        let elm = document.createElement('a');  // CREATE A LINK ELEMENT IN DOM
        elm.href = URL.createObjectURL(data);  // SET LINK ELEMENTS CONTENTS
        elm.setAttribute('download', filename); // SET ELEMENT CREATED 'ATTRIBUTE' TO DOWNLOAD, FILENAME PARAM AUTOMATICALLY
        elm.click();                             // TRIGGER ELEMENT TO DOWNLOAD
        elm.remove();
     
    catch(err) 
        console.log(err);
       

在代码中调用函数我使用了匿名函数(普通函数我希望也可以使用):

(async () => 
                await download('/api/hrreportbyhours',"Report "+getDDMMYYY(new Date())+".xlsx");    
                await setBtnLoad1(false);
            )();

【讨论】:

以上是关于在函数中获取 blob 下载状态的主要内容,如果未能解决你的问题,请参考以下文章

如何在 Azure blob 下载中获取 blob 下载进度

RN从IOS中的URL获取blob下载docx或pdf

使用 Azure 函数从 Azure Blob 存储下载文件会返回不同的文件大小

下载时获取 Azure Block Blob 属性 (BlockBlobClient.download)

如何下载(或以 blob 形式获取)用于流式传输 HTML5 视频的 MediaSource?

在 Azure 门户中上传 Blob 时如何获取发件人 IP