【问题标题】:Fetch blob downloaded status in a function在函数中获取 blob 下载状态
【发布时间】: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:我希望它是stackoverflow.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; ... } ) 就足够了。

标签: javascript node.js reactjs


【解决方案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);
            })();

【讨论】:

    猜你喜欢
    • 2020-10-14
    • 2012-05-02
    • 2020-12-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-02-17
    相关资源
    最近更新 更多