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 ...
随机推荐
- BZOJ2821 作诗(Poetize) 主席树 bitset
原文链接https://www.lydsy.com/JudgeOnline/problem.php?id=2821 题目传送门 - BZOJ2821 题意 $n$ 个数,$m$ 组询问,每次问 $[l ...
- Linux安装Tomcat-Nginx-FastDFS-Redis-Solr-集群——【第十一集之安装FastDFS】
1,安装FastDFS之前,先安装libevent工具包. yum -y install libevent 2,安装libfastcommonV1.0.7工具包.有可能找到新版本的zip压缩包:lib ...
- quratz线程
1.线程 在 Quartz 中,有两类线程,Scheduler 调度线程和任务执行线程,其中任务执行线程通常使用一个线程池维护一组线程. 2.调度线程 下面说明两种调度线程: Scheduler 调度 ...
- TMS320DM642开发之Bug1-Memory map error:READ access by cpu to address 0x1b3f018(Device Config Space)which is not supported in simulator
load程序到DM642开发板上之后,点击了run按钮出现了如下的错误: Memory map error:READ access by cpu to address 0x1b3f018(Device ...
- 爬虫2 urllib3用法
import urllib3 import json # 实例化一个连接池 # http = urllib3.PoolManager() # res = http.request('get','htt ...
- gevent实现生产者消费者
from gevent import monkey;monkey.patch_all()from gevent.queue import Queue #队列 gevent中的队列import geve ...
- Codeforces 1082D Maximum Diameter Graph (贪心构造)
<题目链接> 题目大意:给你一些点的最大度数,让你构造一张图,使得该图的直径最长,输出对应直径以及所有的边. 解题分析:一道比较暴力的构造题,首先,我们贪心的想,要使图的直径最长,肯定是尽 ...
- windows下z3安装
从 github 上 clone Z3 git clone https://github.com/Z3Prover/z3.git 命令行中进入 Z3 文件夹,执行命令: python scripts/ ...
- D - GCD HDU - 1695 -模板-莫比乌斯容斥
D - GCD HDU - 1695 思路: 都 除以 k 后转化为 1-b/k 1-d/k中找互质的对数,但是需要去重一下 (x,y) (y,x) 这种情况. 这种情况出现 x ,y ...
- SpringBoot使用数据库
这一篇简单介绍一下SpringBoot配置数据库的配置(依赖和application.properties),以下全是以本地数据库为例子,具体用户名密码地址都根据实际去修改. Mysql数据库: po ...