前言
图片、音频、视频等资源文件,我在之前的项目中都是采用,直接放到webContent
路径下,然后在页面直接访问。这样就会存在一个安全性问题,就是无论什么用户或者游客,只要知道文件的URL
就可以通过在浏览器地址栏输入URL
直接获取到。
最近在浏览网站的时候,无意间接触到了Blob
对象,经过研究终于可以实现从服务器其他路径(不在webContent
路径下)获取文件,并进行显示或播放的功能了。其原理是,首先通过ajax
请求,获取blob
对象,在这个过程中就可以进行访问限制(例如,访问时检测用户是否登录等)。然后通过js
获取blob
对象的路径,然后赋给标签。
后台代码
后台代码和下载文件的代码是一样的,示例如下:
/*
* 在这里可以进行权限验证等操作
*/
//创建文件对象
File f = new File("E:\\test.mp4");
//获取文件名称
String fileName = f.getName();
//导出文件
String agent = getRequest().getHeader("User-Agent").toUpperCase();
InputStream fis = null;
OutputStream os = null;
try {
fis = new BufferedInputStream(new FileInputStream(f.getPath()));
byte[] buffer;
buffer = new byte[fis.available()];
fis.read(buffer);
getResponse().reset();
//由于火狐和其他浏览器显示名称的方式不相同,需要进行不同的编码处理
if(agent.indexOf("FIREFOX") != -1){//火狐浏览器
getResponse().addHeader("Content-Disposition", "attachment;filename="+ new String(fileName.getBytes("GB2312"),"ISO-8859-1"));
}else{//其他浏览器
getResponse().addHeader("Content-Disposition", "attachment;filename="+ URLEncoder.encode(fileName, "UTF-8"));
}
//设置response编码
getResponse().setCharacterEncoding("UTF-8");
getResponse().addHeader("Content-Length", "" + f.length());
//设置输出文件类型
getResponse().setContentType("video/mpeg4");
//获取response输出流
os = getResponse().getOutputStream();
// 输出文件
os.write(buffer);
}catch(Exception e){
System.out.println(e.getMessage());
} finally{
//关闭流
try {
if(fis != null){
fis.close();
}
} catch (IOException e) {
System.out.println(e.getMessage());
} finally{
try {
if(os != null){
os.flush();
}
} catch (IOException e) {
System.out.println(e.getMessage());
} finally{
try {
if(os != null){
os.close();
}
} catch (IOException e) {
System.out.println(e.getMessage());
}
}
}
}
前端代码
Javascript
代码:
//创建XMLHttpRequest对象
var xhr = new XMLHttpRequest();
//配置请求方式、请求地址以及是否同步
xhr.open('POST', './play', true);
//设置请求结果类型为blob
xhr.responseType = 'blob';
//请求成功回调函数
xhr.onload = function(e) {
if (this.status == 200) {//请求成功
//获取blob对象
var blob = this.response;
//获取blob对象地址,并把值赋给容器
$("#sound").attr("src", URL.createObjectURL(blob));
}
};
xhr.send();
HTML代码:
<video id="sound" width="200" controls="controls"></video>