H5界面预览或下载文件(Minio或本地文件)

本文介绍了在H5界面中通过Minio服务实现文件预览和下载的两种方法,包括利用Minio自带的预览地址和通过后端获取文件流。同时讨论了安全性及跨域问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

H5界面预览或下载文件(Minio或本地文件)

一、使用场景

最近有个老系统,需要添加图片预览和文件下载功能,文件保存在Minio上。前端需要在H5界面上,使用js获取文件信息进行图片的预览和文件下载

先说一下两种情况,本地文件(或者通过IO流获取的文件)只能通过流方式传输到前端,然后进行展示或下载。

但是Minio上的文件,有两种方式可以处理:1.通过Minio自带的预览地址直接展示,比较方便但是会暴露Minio地址(需要安全性考虑),而且一般用于图片之类的可以直接预览的文件格式;2.读取文件流,和本地文件一样传输到前端,然后处理展示或下载,适用于类似文档表格等格式的文件。

可以先看下效果
在这里插入图片描述


话不多说,直接上代码

Minio上传下载相关内容就不赘述了,直接依赖就能用了。

二、Minio自带预览地址

Java代码实现

@RequestMapping("/preViewFile")
@ResponseBody
public String preViewFile(){
    try {
            return minioClient.getPresignedObjectUrl(Method.GET, bucketName, fileName, 60 * 60 * 24,null);
        } catch (Exception e) {
            e.printStackTrace();
        }
}
//第一个参数是请求方式,默认给GET就行,bucketName是保存的桶名称,fileName就是Minio文件保存的地址,第四个参数是链接有效时间,最后一个请求参数,一般给Null就行。

JS代码实现

//按钮随便写一个,onclick调用onPrewViewFile()就行,这里就不赘述了!
function onPrewViewFile() {
	top.$.modal.loading('文件加载中');
	$.ajax({
            cache: true,
            type: "get",
            url: prefix + "/preViewFile",
            data: {},//如果有参数,可以在这里添加请求参数,get也可以改成post
            async: false,
            error : function(request) {
                top.$.modal.closeLoading();
                $.modal.alertError("系统错误");
            },
            success: function(data) { 
                window.open(data, "_blank", "width=800,height=600,left=" + (screen.width/2 - 400) + ",top=" + (screen.height/2 - 300));
                top.$.modal.closeLoading();
            }
        });
}
//JAVA后台返回的值就是地址,所以直接使用window.open打开就可以预览了!!!  "_blank"是新开窗口,再后面是窗口大小和位置,可以自定义(就是style样式)

三、文件流形式展示和下载

JAVA代码实现

	@RequestMapping("/preViewFile2")
    @ResponseBody
    public void preViewFile2(HttpServletResponse response){
        try {
            //本地文件获取流方式
            InputStream inputStream = new FileInputStream(new File("filePath"));
            //Minio获取流方式
            InputStream inputStream = minioClient.getObject(bucketName, "filePath");
            //请求返回的response
            ServletOutputStream outputStream = null;
            try {
                //设置响应头属性,第一个是附件名
                response.setHeader(HttpHeaders.CONTENT_DISPOSITION, "inline;filename=" + "fileName");
                //第二个允许外部客户端访问,解决跨域问题等,如果有其他要求,可自行添加
                response.setHeader(HttpHeaders.ACCESS_CONTROL_EXPOSE_HEADERS, HttpHeaders.CONTENT_DISPOSITION);
                //如果要给前端赋值类型,取消下面这行注释,fileType换成自己的文件类型即可!
                //response.setHeader(HttpHeaders.CONTENT_TYPE,"filType");
                
                //将流写入response的输出流中
                outputStream = response.getOutputStream();
                byte b[] = new byte[1024];
                int n;
                while ((n = inputStream.read(b)) != -1) {
                    outputStream.write(b, 0, n);
                }
                outputStream.flush();
            } catch (Exception e) {
                //有异常抛出去给外层统一处理
                throw e;
            } finally {
                if (inputStream != null) {
                    inputStream.close();
                }
                if (outputStream != null) {
                    outputStream.close();
                }
            }
        }catch (Exception e){
            logger.info("获取文件流报错", e);
            response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
        }
    }

//将文件流保存到response中传给前端进行处理

JS代码实现

需要注意的是,图片可以预览,但是文档类的需要其他插件才行,所以这里只做图片预览和文件下载!!!

//按钮随便写一个,onclick调用onPrewViewFile2()就行,这里就不赘述了!

function onPrewViewFile2() {
    	top.$.modal.loading('文件加载中');
    	//新建ajax请求
    	var xhr = new XMLHttpRequest();
    	//请求方式、地址和是否异步,如果是带参数,可以将参数放入最后的xhr.send(params)中即可
    	xhr.open("GET", prefix + "/preViewFile2", true);
    	//相应类型是二进制
        xhr.responseType = "blob";
        xhr.onload = function(e) {
            //如果返回是200,正常
            if (this.status == 200) {
                var blob = this.response;
                //fileType我原本是通过表格名称截取传进方法的,如果不通过方法传进来,则使用下面这条语句
                //也可以通过let contentType = response.headers.get('Content-Type');在后端设置好后,前端获取
                if (fileType == 'jpeg' ||fileType == 'jpg' || fileType == 'png') {
                	//如果是文件格式
                    var reader = new FileReader();
                    reader.onloadend = function () {
                        let image = new Image();
                        //文件地址赋值给image.src(文件地址在后面的reader.readAsDataURL(blob)会生成)
                        image.src = reader.result;
                        //给浏览器的请求地址,如果不给也可以预览,但是chrome浏览器左上角会有个圈圈一直转啊转,转的头晕。
                        //加上请求地址就好了,其他浏览器暂时没看到此问题
                        let url = URL.createObjectURL(blob);
                        //打开新的窗口,设置窗口的样式即可
                        let popupWindow = window.open(url, "_blank", "width=800,height=600,left=" + (screen.width / 2 - 400) + ",top=" + (screen.height / 2 - 300));
                        popupWindow.document.write('<html><head><title>图片预览</title></head><body style="margin: 0; padding: 0; text-align: center;">');
                        popupWindow.document.write('<img src="' + image.src + '" alt="Preview Image" style="max-width: 100%; max-height: 100vh;">');
                        popupWindow.document.write('</body></html>');
                    }
                    //将二进制文件生成对应的数据地址
                    reader.readAsDataURL(blob);
                    top.$.modal.closeLoading();
                } else {
                    //如果是其他格式,则只允许下载
                    //创建一个a链接组件,用于下载
                    let a = document.createElement('a');
                    //将二进制数据创建成可下载的地址
                    let url = URL.createObjectURL(blob);
                    //赋值给a组件
                    a.href = url;
                    
                    //fileName我原本是表格获取,如果没有,则使用下面这两行代码即可
                    //let contentDisposition = response.headers.get('Content-Disposition');
    				//let fileName = contentDisposition.split('filename=')[1];
                    
                    //将文件名赋值给a.download,用于下载名
                    a.download = fileName;
                    //添加上a组件后,主动click实现下载效果。
                    document.body.appendChild(a);
                    a.click();
                    //释放上面创建的url对象,避免内存过大
                    window.URL.revokeObjectURL(url);
                    top.$.modal.msgSuccess("下载成功");
                }
            }else {
                top.$.modal.closeLoading();
                top.$.modal.alertError("请求错误");
            }
        };
		//发送请求
        xhr.send();
}

//注意:如果 top.$.modal.alertError("请求错误")报错,可能是缺少对应的js包,这只是个提示,可以删除掉。

总结

  1. Minio服务本身带有文件预览功能,我们只用获取对应地址直接打开就可以预览了,但是这会暴露Minio地址,如果对安全性有要求,不建议!
  2. 流形式的实现会比较复杂,需要后端获取流后传输到前端进行处理,但是对于预览和下载都可以适用,也是不错的方式。

如果需要多文件上传样式和按钮的,可以看一下另一篇文章,实现多文件的选择和删除。

多文件上传按钮样式

🙉在小小的电脑上面敲呀敲呀敲,写短短的代码,埋小小的坑🙈

🙉在大大的电脑上面敲呀敲呀敲,写大大的代码,埋大大的坑🙈

🙉在特别大的电脑上面敲呀敲呀敲,写特别大的代码,埋特别大的坑🙈

🙉优秀的你肯定是一个不爱写Bug并且爱点赞关注的靓仔吧!🙈

### 回答1: Active Directory域服务是一种由微软公司开发的网络服务,它提供了一种集中管理和控制网络资源的方式。它可以在一个域中集中管理用户、计算机、应用程序和其他网络资源,从而提高了网络的安全性和可管理性。Active Directory域服务还提供了一些高级功能,如单点登录、组策略管理和域名系统(DNS)集成等,使得网络管理员可以更加轻松地管理和维护网络。 ### 回答2: Active Directory域服务(Active Directory Domain Services,简称AD DS)是微软公司的一项用于管理和组织网络资源的目录服务。它是一种基于LDAP(轻量级目录访问协议)的目录服务,可以让用户和管理员方便地管理和访问网络中的资源。 AD DS的主要功能包括用户身份认证、访问控制、组管理和资源管理等。通过AD DS,管理员可以集中管理和配置用户和计算机的访问权限,确保系统安全。同时,AD DS还提供了域的集中管理功能,管理员可以通过域控制器管理域中的所有对象,并在域中实施策略。 AD DS还支持单点登录功能,用户只需在登录到域之后,即可自动访问到所属域中的资源,而无需再次输入用户名和密码。这大大提高了用户的工作效率。 此外,AD DS还支持多域架构,可以通过建立信任关系实现跨域资源的访问和管理。管理员可以维护多个域之间的信任关系,实现用户和资源的统一管理。 总而言之,AD DS是一种强大的目录服务,可以实现用户和资源的集中管理和访问控制,提高网络系统的稳定性和安全性。它是企业网络管理的重要组成部分,为企业提供了高效的身份认证和资源管理功能,增强了企业的生产力和安全性。
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值