从node下载文件到前端本地,get方式的url用a标签模拟点击无法下载

如题,试图通过get请求从node下载文件(文件格式统一为zip)到前端本地,尝试了两种方式:

  1. 将拼接好的url直接输入浏览器地址栏。
  2. 前端拼接好url后模拟a标签点击进行下载。

方式1,正常下载无误,下载的zip能正常解压
方式2,node本地文件无误,能正常解压,然而下载到前端时,chrome会有警告,警告如下,且下载到前端本地的文件无法解压

Resource interpreted as Document but transferred with MIME type

根据提示在node后台处理get请求时,将ContentType设置为text/html后,警告消失,然而下载到前端本地的文件无法正常解压。
一直觉着是ContentType的设置问题,但是搜索并尝试了半天依旧没有解决。

下附前端模拟a标签点击下载代码

        $.ajax({
            type:"POST",
            url:"/api/download_reports",
            data:JSON.stringify(msgArr),
            dataType:'json',
            contentType:"application/json; charset=utf-8",
            success:function(response){
                console.log(response)
                if(response.status == 200){
                    path = file+'?dir='+response.data.dir+'&name='+response.data.fileName;  
                    console.log(path) 
                    let a = document.createElement('a');
                    a.href = path;
                    a.download = response.data.fileName;
                    document.body.appendChild(a);
                    a.click();
                    document.body.removeChild(a);
                }
            },
            
        });

如下为node端处理get请求的代码

app.get('/api/download',function(req, res, next){
        var currDir = path.join(__dirname,req.query.dir),
            fileName = req.query.name,
            currFile = path.join(currDir,fileName),
            fReadStream;
    
        fs.exists(currFile,function(exist) {
            if(exist){
                res.set({
                    "Content-type":"application/octet-stream",
                    "Content-Disposition":"attachment;filename="+encodeURI(fileName)
                });
                fReadStream = fs.createReadStream(currFile);
                fReadStream.on("data",(chunk) => res.write(chunk,"binary"));
                fReadStream.on("end",function () {
                    res.end();
                });
            }else{
                res.set("Content-type","text/html");
                res.send("file not exist!");
                res.end();
            }
        });
    });

不知道问题出在哪里,知道的小伙伴还请不吝赐教orz

阅读 3.8k
1 个回答

这个问题的答案得分开来说,首先说mime,主要是因为如上处理的话,你传的response的content-type为application/octet-stream,而前端浏览器默认以为你传的是text/html,所以会报错。
然后说说这个模拟a标签点击下载为什么不行,具体请参考我对自己的回答,当然回头会整理一篇博客记录这个自己给自己挖的坑,整理好了我会加上链接,有说的不对的地方,欢迎交流指正~

推荐问题
宣传栏