分片加载的实现是基于 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, //分页关键,是否禁用流的形式加载
标签:Ranges,HttpContext,Accept,Current,Length,分片,pdfjs,Response From: https://www.cnblogs.com/liudd123/p/17384989.html