pdfjs分片

发布时间 2023-05-09 14:44:21作者: 刘朵朵

分片加载的实现是基于 HTTP-RANGE 的,即服务端的文件接口如果实现了HTTP-RANGE,pdf.js会默认去执行分

片加载的策略。

 

也就是第一次请求时,服务器返回200,同时返回响应头Accept-Ranges

Accept-Ranges: bytes (表明服务器支持分片加载)

Content-Length: 408244 (表明该文件的所有字节大小)

注意:

  1. 跨域
  2. 浏览器默认只允许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, //分页关键,是否禁用流的形式加载