blob 其实是 h5 表征的 Blob 对象数据,具体请看文档。我们可以使用 Blob 对象隐藏真实的资源路径,在一定程度上可以起到数据的加密性,更多的是为了干扰爬虫。
比如日常使用的一些音频,视频,图片,我们都可以使用其 Blob 二进制数据流来表征数据,而非使用 uri,就像经常用到的 image src 的 dataUrl。
要使用 blob 来表征数据资源,需做到以下两点:
1、服务端返回的为资源的二进制数据
2、前端接收到二进制数据后,使用 URL.createObjectURL(blobData) 方法将服务端返回的二进制数据转换为 blob 的 url 资源挂载到相应的资源对象。
我们只是实例讲解下如何生成 blob 资源地址,生产中是很少会将一个资源以二进制流的方式返回给前端进行 Blob “加密”的,因为服务端需要将相应的资源打开读取,会消耗对应的内存,比如一个视频如果50M,那我们服务端返回其二进制数据时,就要消耗 50M 的服务器内存将文件载入,然后返回给前端,这代价略大,而且网络传输相应速度也不允许,如果返回个 500M 的二进制数据,估计就会有很大的卡顿了。
生产场景往往是对切片格式的视频 m3u8 地址进行 blob 格式处理,其实并不是为了加密,因为浏览器还是会解析 blob 并去 get 请求对应的 m3u8 地址,使用 blob uri 的好处在于可以在一定层度上干扰爬虫。
前段实现
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Blob Url</title>
</head>
<body>
<video id="video" width="400" controls="controls"></video>
<script type="text/javascript">
//创建XMLHttpRequest对象
var xhr = new XMLHttpRequest();
//配置请求方式、请求地址以及是否同步
xhr.open('POST', '/HOME/Video', true);
//设置请求结果类型为blob
xhr.responseType = 'blob';
//请求成功回调函数
xhr.onload = function(e) {
if (this.status == 200) {//请求成功
//获取blob对象
var blob = this.response;
//获取blob对象地址,并把值赋给容器
document.getElementById("video_player").src = URL.createObjectURL(blob);
}
};
xhr.send();
</script>
</body>
</html>
<div>
<video id="video_player" width="660" height="364" controls="controls"></video>
</div>
<script>
//创建XMLHttpRequest对象
var xhr = new XMLHttpRequest();
//配置请求方式、请求地址以及是否同步
xhr.open('POST', '/Home/Video', true);
//设置请求结果类型为blob
xhr.responseType = 'blob';
//请求成功回调函数
xhr.onload = function (e) {
if (this.status == 200) {//请求成功
//获取blob对象
var blob = this.response;
var video = document.getElementById('video_player');
//获取blob对象地址,并把值赋给容器
var obj_url = window.URL.createObjectURL(blob);
video.src = obj_url;
//video.play();
//setTimeout("revokeUrl('" + obj_url + "')", "2000"); //设置在2秒后停止播放
}
};
xhr.send();
function revokeUrl(url) {
window.URL.revokeObjectURL(url);
}
</script>
C# 后台加载视频文件
using System;
using System.IO;
using System.Web.Mvc;
/// <summary>
/// 加载视频流
/// </summary>
public void Video()
{
//这里需要获取全路径 如:D:\project\images\video\products\video.mp4
string filePath = this.Server.MapPath("~/Content/0dd36bd6673c77960a3946ae33ea8ec9.mp4");
System.IO.FileInfo fileInfo = new System.IO.FileInfo(filePath);
if (fileInfo.Exists == true)
{
FileStream fs = new FileStream(filePath, FileMode.Open);
byte[] bytes = new byte[(int)fs.Length];
fs.Read(bytes, 0, bytes.Length);
fs.Close();
//Response.AddHeader("Content-Disposition", "attachment; filename=" + HttpUtility.UrlEncode(fileInfo.Name));
Response.AddHeader("Content-Length", "" + fileInfo.Length.ToString());
Response.AddHeader("Content-Transfer-Encoding", "binary");
Response.ContentType = "application/octet-stream";
Response.ContentEncoding = System.Text.Encoding.UTF8;
Response.BinaryWrite(bytes);
Response.Flush();
Response.End();
}
}