文件地址没有暴露在公网,无法通过文件url直接下载文件。
要下载的文件内容可能是根据用户请求动态生成的,如导出Excel数据表。
后端需要鉴权验证用户提交的下载请求。
前端发送get/post请求,携带header信息(如token用于鉴权),后端接收请求,完成鉴权后,读取对应的文件,将文件以文件流的形式发送给浏览器,浏览器完成下载。
我们把这种方式叫做Blob方式下载。
Blob 对象表示一个不可变、原始数据的类文件对象。Blob 表示的不一定是JavaScript原生格式的数据。
我们以下载图片为例,使用axios来做前端异步下载请求。
get方式请求中,我们要在header中携带token信息,这个token就是你在系统中的通行证,一般是你在登录的时候后端给你的token,相当于一张游乐场的门票,有了这张门票,你可以到游乐场里游玩任意项目,只是在游玩时给工作人员出示这个token门票就可以了。
并且还要告诉后端,需要后端返回blob
类型的数据,使用responseType: \'blob\'
。
axios.get(\'http://localhost:9998/download.php\', { headers: { \'token\': \'1234512345\' }, responseType: \'blob\' }).then((res) => { if (res.data.type !== \'application/octet-stream\') { alert(\'下载失败\'); return false; } const blob = new Blob([res.data], { type: \'image/jpeg\' }) let a = document.createElement("a"); let objUrl = URL.createObjectURL(blob); a.href = objUrl; a.download = \'abc.jpg\' //文件名 a.click(); URL.revokeObjectURL(objUrl); // 释放内存 document.body.removeChild(a); alert(\'下载成功\'); }).catch((err) => { console.log(err); alert(\'下载失败\'); });
我们拿到后端返回的blob对象数据后,在页面上创建一个a标签,然后模拟点击事件,将blob数据保存成文件。注意URL.createObjectURL(blob)
将blob保存在内存中,下载完后记得释放内存哦。
在后端download.php中,先要在header中允许接收token,如果是跨域请求那就应该还要设置header("Access-Control-Allow-Origin: *");
允许跨域请求。
header("Access-Control-Allow-Headers: Content-Type, Authorization, X-Requested-With, token"); $token = isset($_SERVER[\'HTTP_TOKEN\']) ? $_SERVER[\'HTTP_TOKEN\'] : \'\'; if ($token != \'1234512345\') { echo \'error.\'; exit; } $file = \'../file/cc.jpg\'; if (!file_exists($file)) { header(\'HTTP/1.1 404 Not Found\'); exit; } $fileSize = filesize($file); //下载文件需要用到的头 header("Content-type: application/octet-stream"); header("Accept-Ranges: bytes"); header("Accept-Length:".$fileSize); $fp = fopen($file, "rb"); $buffer = 1024; $fileCount = 0; //向浏览器发送数据 while(!feof($fp) && $fileCount < $fileSize){ $cont = fread($fp, $buffer); $fileCount += $buffer; echo $cont; } fclose($fp);
接着就是验证token是否正确,上述代码中的验证过程是伪代码,实际开发中应该根据业务需求,按照一定的算法验证token。token里面可能含有用户信息和过期时间等数据。
然后判断要下载的文件是否存在,这个文件可能不在web目录下,用户无法直接通过url访问。
最后就是读取文件流,发送给浏览器。
本文地址:https://www.stayed.cn/item/280
转载请注明出处。
本站部分内容来源于网络,如侵犯到您的权益,请 联系我