前端文件下载,a标签下载,ajax下载亲测有效

前端文件下载,a标签下载,ajax下载亲测有效,第1张

这段时间项目需要下载文件,刚开始直接用a标签的href加后端地址的方式就可以下载,这类方法可以下载zip文件等浏览器不能识别的文件,但是遇到下载txt和图片等文件就莫得办法了,因为浏览器会自动打开。 然后就去网上搜了一下,发现有很多人都说直接在a标签里加一个download属性就好了,并且这个可以设置文件名,但是很多都没有接受什么时候加这个属性会生效,所以用我亲自踩完坑的经历来解释一下,先看一个列子,比如:
点击下载

各位可以运行上面这段代码试一试,地址是有效的

但是,很灵性的但是哈。(各位,重点来了,一定要仔细看) 但是这种方法根本不管用!浏览器还是直接打开图片了,原因是a标签加这个属性得分情况,必须要在同源(同域名、同协议、同端口号)时,才会生效,什么概念呢? 比如说前端项目布在http://192.168.88:8888 这个服务器上面,后端项目也布在同一个服务器同一个端口号下面,这种情况才可以下载,否则的话都不行。 并且就算是以上这种情况前端在本地调试的时候也是不会下载的,原因是在本地调试的时候前端地址一般都是http://localhost:300,很明显和后端地址不是同源嘛。 虽然做了反向代理,但还是不会下载的,不过推到线上就生效了。所以各位在用a标签下载的时候需要注意是否同源(主要看发布后是否同源)

既然说了ajax的方法肯定就还没完嘛,接下来讲一下第二种

先上代码:

//ajax方法
        const xhr = new XMLHttpRequest();
        xhr.open('GET', 'http://www.kaotop.com/file/tupian/20220528/jkjgkEfvpUPVyRjUImniVslZfWPnJuuZ.png', true);
        xhr.responseType = 'blob';
        xhr.onload = function () {
            if (this.status === 200) {
                const fileName = 'test.png';
                const blob = new Blob([this.response]);
                const blobUrl = window.URL.createObjectURL(blob);
                const a = document.createElement('a');
                a.href = blobUrl;
                a.download = fileName;
                a.click();
                window.URL.revokeObjectURL(blobUrl);
            }
        };
        xhr.send();

        // 用fetch发送请求
        fetch('http://www.kaotop.com/file/tupian/20220528/jkjgkEfvpUPVyRjUImniVslZfWPnJuuZ.png').then((res) => {
            res.blob().then((blob) => {
                const blobUrl = window.URL.createObjectURL(blob);
                console.log(blob);
                console.log(blobUrl);
                // 这里的文件名根据实际情况从响应头或者url里获取
                const filename = 'user.jpg';
                const a = document.createElement('a');
                a.href = blobUrl;
                a.download = filename;;
                a.click();
                window.URL.revokeObjectURL(blobUrl);
            });
        });

上面的代码也是可以运行的,地址有效

买一送一再来了一个fetch的 这种方法就不管同源不同源都会下载了,但是这毕竟是ajax请求了嘛,所以会涉及到跨域的问题,需要解决一下跨域问题,不过现在都会配置反选代理,所以也不是上面问题了,但是会有些小细节(如果不细节效果也出不来) 下面看实际项目中的用法 正常来说在项目中请求数据时地址都会写成/aip/xxx/xxx的对吧,所以这个地方一般会写成fetch("/api/xxx/xxx.txt"),对吧,看似很合理,但这样写了点击下载没有反应,也不报错,network也请求成功,但就是不会下载,为什么呢?我也不知道,哪个大佬要是知道一定评论解释一下。 但是我有个解决方案,只要把api换成后端地址就ok了,写成这样:fetch("/http://192.168.88:8888/xxx/xxx.txt"),前面那个"/"必须留着,否则就包跨域的错了,或者也可以写成fetch("http:localhost:3000/http://192.168.88:8888/xxx/xxx.txt")也可以,但是这种前面会被写死,等上线的时候还得改成线上的地址,所以推荐第一种,第一种会自动补全前面的地址,请求完的结果是:

 接下来看项目实际代码:

 

下载结果:  这一看就知道是react加antd的项目了 好了,具体两种用法就是这样了,都是自己亲测有效的,大家根据自己情况选择。其实还有其他的方式,一是我懒了没去研究,二是我觉得有这两种就够用了

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/web/1322350.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-06-12
下一篇 2022-06-12

发表评论

登录后才能评论

评论列表(0条)

保存