pdfjs分片
分片加载的实现是基于 HTTP-RANGE 的,即服务端的文件接口如果实现了HTTP-RANGE,pdf.js会默认去执行分
片加载的策略。
也就是第一次请求时,服务器返回200,同时返回响应头Accept-Ranges
Accept-Ranges: bytes (表明服务器支持分片加载)
Content-Length: 408244 (表明该文件的所有字节大小)
注意:
- 跨域
-
浏览器默认只允许js读取以下的响应头,而Accept-Ranges: bytes是不支持的,这就造成pdf.js读取Accept-Ranges时,读到了null值,认为你的服务器不支持分片,故整个文件下载了。
解决方法:在服务端的返回响应头上增加:
'Access-Control-Expose-Headers':'Accept-Ranges,Content-Range'
这样pdf.js才能读取到Accept-Ranges响应头,进而执行分片的策略。
1 public void GetRangeStreamByAttId(string id) 2 { 3 if (Guid.TryParse(id, out Guid Id)) 4 { 5 var att = AttachmentBLL.GetAttachment(Id); 6 if (att != null) 7 { 8 var serverPath = ConfigCenter.ServerUploadFilePath; 9 var file = $"{serverPath}{att.AttachmentPath}"; 10 int startByte, endByte, totalByte; 11 using (FileStream stream = new FileStream(file, FileMode.Open, FileAccess.Read, FileShare.Read, 4096, true)) 12 { 13 // 断点续传 14 if (HttpContext.Current.Request.Headers.AllKeys.Any(a => a.ToLower() == "range")) 15 { 16 string[] range = Regex.Replace(HttpContext.Current.Request.Headers.GetValues("Range")[0], "[^0-9\\-]", "").Split(new char[] { '-' }, StringSplitOptions.RemoveEmptyEntries); 17 startByte = Convert.ToInt32(range[0]); 18 totalByte = (int)stream.Length; 19 20 // 下载结束位置 21 if (range.Length > 1) 22 { 23 endByte = int.Parse(range[1]); 24 } 25 else 26 { 27 endByte = totalByte - 1; 28 29 } 30 // 返回http状态 31 HttpContext.Current.Response.StatusCode = 206; 32 } 33 else 34 { 35 // 文件总大小 36 totalByte = (int)stream.Length; 37 // 下载起始位置 38 startByte = 0; 39 // 下载结束位置 40 endByte = totalByte - 1; 41 // 返回http状态 42 HttpContext.Current.Response.StatusCode = 200; 43 } 44 // 需要下载字节数 45 int length = endByte - startByte + 1; 46 HttpContext.Current.Response.AddHeader("Access-Control-Expose-Headers", "Accept-Ranges,Content-Range"); 47 HttpContext.Current.Response.AddHeader("Accept-Ranges", "bytes"); 48 HttpContext.Current.Response.AddHeader("Content-Range", "bytes " + startByte + "-" + endByte + "/" + totalByte); 49 HttpContext.Current.Response.ContentType = "application/octet-stream"; 50 HttpContext.Current.Response.AddHeader("Content-Length", length.ToString()); 51 using (BufferedStream bis = new BufferedStream(stream)) 52 { 53 bis.Position = startByte; 54 int len = 0; 55 byte[] buff = new byte[1024 * 64]; 56 using (BufferedStream bos = new BufferedStream(HttpContext.Current.Response.OutputStream)) 57 { 58 while ((len = bis.Read(buff, 0, buff.Length)) != -1) 59 { 60 if (length <= len) 61 { 62 bos.Write(buff, 0, length); 63 break; 64 } 65 else 66 { 67 length -= len; 68 bos.Write(buff, 0, len); 69 } 70 } 71 } 72 } 73 74 } 75 HttpContext.Current.Response.End(); 76 } 77 } 78 else throw new ExceptionCustom("参数错误"); 79 80 }
pdfjs需要修改
pdfjs支持pdf分页操作,无需单独再行添加js方法,找到view.js
1 "disableAutoFetch": true, //是否禁用自动获取,true为禁用自动获取,开启分页 2 "disableFontFace": false, 3 "disableRange": false, //是否禁用range获取文件,false表示支持分页请求头 4 "disableStream": true, //分页关键,是否禁用流的形式加载
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
后端根本不用写方法,
请求iis之类的服务器,就会返回
Accept-Ranges: bytes (表明服务器支持分片加载)
Content-Length: 408244 (表明该文件的所有字节大小),
但是分片没起作用,那是因为在返回头里没加'Access-Control-Expose-Headers':'Accept-Ranges,Content-Range',
在IIS的的Http响应标头里加上就行了。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· Docker 太简单,K8s 太复杂?w7panel 让容器管理更轻松!