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 ...
随机推荐
- Selenium自动化测试框架的搭建
说 起自动化测试,我想大家都会有个疑问,要不要做自动化测试? 自动化测试给我们带来的收益是否会超出在建设时所投入的成本,这个嘛别说是我,即便是高手也很难回答,自动化测试的初衷是美好的,而测 ...
- 2018牛客网暑假ACM多校训练赛(第四场)B Interval Revisited 动态规划
原文链接https://www.cnblogs.com/zhouzhendong/p/NowCoder-2018-Summer-Round4-B.html 题目传送门 - https://www.no ...
- nexus、maven私服仓库(一)
下载地址:http://www.sonatype.com/download-oss-sonatype 将下载好的nexus解压到指定的目录下,我这里使用的是nexus-3.14.0-04-win64 ...
- 归并排序(Java实现)
package sort; public class MergeSort { static void msort(int []a,int start,int end){ int mid=(start+ ...
- Scala-Unit4-Scala数组/集合
一.Scala数组 1.数组的定义: 方法一:val arr = new Array[String](3) String代表数据的元素类型.3表示数组的长度 方法二:val arr = Array[I ...
- 【python】常用内建模块
[datetime] No1: 获取当前时间 No2: 时区转换 >>> from datetime import datetime, timedelta, timezone > ...
- BOM 和 DOM
目录 一.BOM 1.什么是BOM 2. 浏览器内容划分 归BOM管的: 归DOM管的: 3. BOM常见方法 二.DOM 1 什么是DOM 2. DOM常见方法 一.BOM 1.什么是BOM BOM ...
- 自己总结的C#编码规范--2.命名选择篇
上一篇文章讲了标识符命名的约定,今天讲下标识符命名的选择. 简单的讲,看到一个标识符一定要可以见名知意. 名字一定要能够表达出标识符的含意 标识符名字必须要表达出该标识符的意义,绝对不可以使用无意义的 ...
- codeforces723----C. Polycarp at the Radio
//AC代码...表示很晕 #include <iostream> using namespace std; ],b[]; int main() { int n,m,cnt; cin &g ...
- jsoup 解析html
http://www.cnblogs.com/jycboy/p/jsoupdoc.html http://www.cnblogs.com/mokafamily/p/3558620.html