PDF.js 分片下载的介绍2:分片下载demo
上一个章节,简要说了以下分片下载的几个特性。今天主要用示例说明一下pdf.js分片下载。
服务器环境:
php7.2
nginx 1.14
ubuntu 18.04
测试浏览器:谷歌浏览器 70.0.3538.110(
第一个场景,直接使用pdf 文件
1.1 代码如下:注意路径使用的是pdf 文件的物理路径
$filePath = ‘…/doc/big.pdf’;
这里是举例,这样作有一个明显的缺点,就是容易被盗链
getDocument 方法中的 rangeChunkSize 参数,就是设置分块大小,默认是64k,可以修改这个数字,来改变
这个例子使用的 1664k ,1m 左右来分片,方便测试。您可以根据具体情况,来调整
PDFJS.getDocument({url:url,rangeChunkSize:6553616,disableAutoFetch:0}).
- <html>
- <head><title>pdf.js展示1,上一页,下一页</title></head>
- <h1>PDF.js Previous/Next example</h1>
- <div>
- <button id="prev">Previous</button>
- <button id="next">Next</button> <span>Page: <span id="page_num"></span> / <span
- id="page_count"></span></span></div>
- <canvas id="the-canvas"></canvas>
- <script src="../js/pdfjs/pdf.js"></script>
- <script src="../js/pdfjs/pdf.worker.js"></script>
- <script>
- var url = '../doc/big.pdf';
- var pdfDoc = null,
- pageNum = 1,
- pageRendering = false,
- pageNumPending = null,
- scale = 0.8,
- canvas = document.getElementById('the-canvas'),
- ctx = canvas.getContext('2d');
- /**
- * Get page info from document, resize canvas accordingly, and render page.
- * @param num Page number.
- */
- function renderPage(num) {
- pageRendering = true;
- // Using promise to fetch the page
- pdfDoc.getPage(num).then(function (page) {
- var viewport = page.getViewport(scale);
- canvas.height = viewport.height;
- canvas.width = viewport.width;
- // Render PDF page into canvas context
- var renderContext = {
- canvasContext: ctx,
- viewport: viewport
- };
- var renderTask = page.render(renderContext);
- // Wait for rendering to finish
- renderTask.promise.then(function () {
- pageRendering = false;
- if (pageNumPending !== null) {
- // New page rendering is pending
- renderPage(pageNumPending);
- pageNumPending = null;
- }
- });
- });
- // Update page counters
- document.getElementById('page_num').textContent = num;
- }
- /**
- * If another page rendering in progress, waits until the rendering is
- * finised. Otherwise, executes rendering immediately.
- */
- function queueRenderPage(num) {
- if (pageRendering) {
- pageNumPending = num;
- } else {
- renderPage(num);
- }
- }
- /**
- * Displays previous page.
- */
- function onPrevPage() {
- if (pageNum <= 1) {
- return;
- }
- pageNum--;
- queueRenderPage(pageNum);
- }
- document.getElementById('prev').addEventListener('click', onPrevPage);
- /**
- * Displays next page.
- */
- function onNextPage() {
- if (pageNum >= pdfDoc.numPages) {
- return;
- }
- pageNum++;
- queueRenderPage(pageNum);
- }
- document.getElementById('next').addEventListener('click', onNextPage);
- /**
- * Asynchronously downloads PDF.
- */
- PDFJS.getDocument({url:url,rangeChunkSize:65536*16,disableAutoFetch:0}).then(function(pdfDoc_) {
- pdfDoc = pdfDoc_;
- document.getElementById('page_count').textContent = pdfDoc.numPages;
- // Initial/first page rendering
- renderPage(pageNum);
- });
- </script>
- </html>
1.2今天第一加载:发现没有出现分片效果。如果您也遇到这种情况,不要着急,很大程度是因为浏览器缓存
1.3 在浏览器中,安Ctrl+alt+delte 键,清除缓存
1.4 清除缓存后,再次刷新页面,发现分片下载功能出现了。
- 后台代码
- <?php
- $filePath = '../doc/big.pdf';
- //普通的方式处理包装pdf文件
- download_file($filePath);
- function download_file($file, $fname = 'chunk.pdf')
- {
- header("Content-Type: application/octet-stream");
- header("Content-Disposition: attachment;filename=$fname");
- echo(file_get_contents($file));
- }
前台js 调用代码
- 。。。。。
- var url = 'download.php';
- var pdfDoc = null,
- pageNum = 1,
- pageRendering = false,
- pageNumPending = null,
- scale = 0.8,
- canvas = document.getElementById('the-canvas'),
- ctx = canvas.getContext('2d');
- 。。。。
2.2 经过清理缓存,发现无法达到分片的效果。
初步总结如下,常规的附件处理方式,会影响分片下载的效果
场景3:使用php 结合httprange,实现分片的效果
3.1 这里是从网上搜集到的分片下载php 函数
代码的核心是,增加head 头,开启分片 Header("Accept-Ranges: bytes"); 至于 Http range 如何计算,就比较繁琐了,这里就不详细介绍了。有兴趣的可以去百度
- <?php
- $filePath = '../doc/big.pdf';
- //分片下载
- chunk_download_file($filePath);
- /**
- * 分篇下载的汉书
- *
- * @param $file
- * @param $fname
- */
- function chunk_download_file($file, $fname = 'chunk.pdf')
- {
- $fhandle = fopen($file, 'rb');//文件句柄
- $fsize = filesize($file);//文件大小
- //断点续传和整个文件下载的判断,支持多段下载
- if (!empty($_SERVER['HTTP_RANGE'])) {
- $range = str_replace("=", "-", $_SERVER['HTTP_RANGE']);
- $match = explode("-", $range);
- $start = $match[1];
- $end = !empty($match[2]) ? $match[2] : $fsize - 1;
- } else {
- $start = 0;
- $end = $fsize - 1;
- }
- if (($end - $start) < ($fsize - 1)) {
- fseek($fhandle, $start);
- header("HTTP/1.1 206 Partial Content");
- header("Content-Length: " . ($end - $start + 1));
- header("Content-Range: bytes " . $start . "-" . $end . "/" . $fsize);
- } else {
- header("HTTP/1.1 200 OK");
- header("Content-Length: $fsize");
- Header("Accept-Ranges: bytes");
- header("Content-Range: bytes " . $start . "-" . $end . "/" . $fsize);
- }
- header("Content-Type: application/octet-stream");
- header("Content-Disposition: attachment;filename=$fname");
- if (!feof($fhandle)) {
- set_time_limit(0);
- $buffer = fread($fhandle, $end - $start + 1);
- echo $buffer;
- flush();
- ob_flush();
- }
- }
demo 下载路径:
https://download.csdn.net/download/niedewang/10804164
3.2 清理调浏览器缓存,发现这种方式可以达到分片下载的效果
经过测试,谷歌浏览器支持的很好,如上图所示,截图就是使用的谷歌浏览器。
但是firefox 在这种场景下,分片效果不理想。具体原因未知
简要的总结
1:前期承诺的demo 放出来了,blog貌似会清理连接地址,不知道是否会删除
2:使用pdf 真实文件路径,分片兼容性最好。但是地址容易泄漏
3:如果使用php 处理,一般的处理程序,不能达到分片效果。需要结合http range特性,但是不知道什么原因,firefox测试下来,效果不好。谷歌浏览器支持的较好,好消息是谷歌浏览器现在占用量是最大的。
4:后面有时间了,会介绍以下使用 x-sendfile 的方式处理附件,无论性能还是兼容性都比php 处理要好
---------------------
作者:只看远方
来源:CSDN
原文:https://blog.csdn.net/niedewang/article/details/84576969
版权声明:本文为博主原创文章,转载请附上博文链接!
PDF.js 分片下载的介绍2:分片下载demo的更多相关文章
- Mongodb主从复制/ 副本集/分片集群介绍
前面的文章介绍了Mongodb的安装使用,在 MongoDB 中,有两种数据冗余方式,一种 是 Master-Slave 模式(主从复制),一种是 Replica Sets 模式(副本集). Mong ...
- 利用PDF.JS插件解决了本地pdf文件在线浏览问题(根据需要隐藏下载功能,只保留打印功能)
我是在IE11和谷歌上做的测试,都可以显示,把做出的东西记录下来,方便大家还有自己学习! 可以在IIS7服务器上也可以下载Tomcat来做服务器 Tomcat下载地址 http://pan.bai ...
- Mongo 整体架构介绍(1)-------分片集群
摘要 在mongo初识文中介绍了mongo与cassandra的主要区别,以及mongo物理部署架构图.本文接着上一篇的mongo 架构图,来继续讲分片集群. 分片介绍 shard key mongo ...
- 【七】MongoDB管理之分片集群介绍
分片是横跨多台主机存储数据记录的过程,它是MongoDB针对日益增长的数据需求而采用的解决方案.随着数据的快速增长,单台服务器已经无法满足读写高吞吐量的需求.分片通过水平扩展的方式解决了这个问题.通过 ...
- 第二章·Elasticsearch内部分片及分片处理机制介绍
一.副本分片介绍 什么是副本分片? 副本分片的主要目的就是为了故障转移,如果持有主分片的节点挂掉了,一个副本分片就会晋升为主分片的角色. 在索引写入时,副本分片做着与主分片相同的工作.新文档首先被索引 ...
- 预览下载的pdf的——pdf.js
1.需要到官网下载源码:https://mozilla.github.io/pdf.js/ 2. function(){ let url='./demo1.pdf'; window.location. ...
- Vue.js +pdf.js 处理响应pdf文件流数据,前端转图片预览不可下载
使用场景及原因 实际业务中,一些说明书或协议仅支持用户在线预览,为避免用户自行下载,并进行修改,引发纠纷,特将文件已文件流的形式,传给前端并转为图片显示,此时可能会有人问,为什么不直接在后端转图片,前 ...
- 小谢第7问:js前端如何实现大文件分片上传、上传进度、终止上传以及删除服务器文件?
文件上传一般有两种方式:文件流上传和base64方式上传,毫无疑问,当进行大文件上传时候,转为base64是不现实的,因此用formData方式结合文件流,直接上传到服务器 本文主要结合vue的来讲解 ...
- pdf.js pdfdom.js使用(转)
开篇语: 最近工作需要做一个借款合同,公司以前的合同都是通过app端下载,然后通过本地打开pdf文件,而喜欢创新的我,心想着为什么不能在线H5预览,正是这个想法,说干就干,实践过程总是艰难的,折腾了3 ...
随机推荐
- AtCoder SoundHound Inc. Programming Contest 2018 E + Graph (soundhound2018_summer_qual_e)
原文链接https://www.cnblogs.com/zhouzhendong/p/AtCoder-SoundHound-Inc-Programming-Contest-2018-E.html 题目 ...
- Ubuntu18.04上安装java
安装java8 sudo add-apt-repository ppa:webupd8team/javasudo apt-get updatesudo apt-get install oracle-j ...
- P2279 [HNOI2003]消防局的设立 贪心or树形dp
题目描述 2020年,人类在火星上建立了一个庞大的基地群,总共有n个基地.起初为了节约材料,人类只修建了n-1条道路来连接这些基地,并且每两个基地都能够通过道路到达,所以所有的基地形成了一个巨大的树状 ...
- HUE的自动化安装部署
HUE=Hadoop User Experience(Hadoop用户体验),直白来说就一个开源的Apache Hadoop UI系统,由Cloudera Desktop演化而来,最后Cloudera ...
- JavaSE| 面向对象的三大特征
1.面向对象的基本特征之一:封装Encapsulation 目的:隐藏实现细节,让使用者方便,让代码更安全 将对象的属性和行为封装起来,其载体就是类.类通常对客户隐藏其实现细节,这就是封装的思想. 封 ...
- utf-8和utf8的区别
utf-8 和 utf8 的区别与使用: "UTF-8" 是标准写法,php 在 Windows 系统里的英文不区分大小写,所以也可以写成 "utf-8".&q ...
- Spring Security(15)——权限鉴定结构 RoleVoter
http://www.cnblogs.com/fenglan/p/5913432.html
- spring cloud 详解
https://www.cnblogs.com/qdhxhz/p/9601170.html SpringCloud(8)---zuul权限校验.接口限流 https://blog.csdn.net/c ...
- notepad++ 去空行
Press Ctrl+H (Replace) Select Extended from SearchMode Put \r\n\r\n in Find What Put \r\n in Replace ...
- asp.net core Session的测试使用心得及注意事项
sp.net-core中Session是以中间件的形式注册使用的.不比asp.net中的使用,直接使用Session就行. 首先在.net-core框架中注入Session中间件,首先在Configu ...