4

I am quite new to client side programming. I am trying to view my pdf in my web using pdf.js. By following the steps in documentation i tried loading pdf with pdf.js. The entire pdf file is getting downloaded in a single request. Now, I would like to do progressive loading (downloading by specifying the range).

I have done the following things at my client and server side.

My client contains two files

  1. form.js and
  2. index.html

CLIENT form.js

'use strict';
var PDF_PATH = ""; //Path of pdf file in web
var PAGE_NUMBER = 1;
var PAGE_SCALE = 1.5;

function renderPage(div, pdf, pageNumber, callback) {
        pdf.getPage(pageNumber).then(function(page) {
        var scale = 1.5;
        var viewport = page.getViewport(scale);

        var pageDisplayWidth = viewport.width;
        var pageDisplayHeight = viewport.height;

        var pageDivHolder = document.createElement('div');
        pageDivHolder.className = 'pdfpage';
        pageDivHolder.style.width = pageDisplayWidth + 'px';
        pageDivHolder.style.height = pageDisplayHeight + 'px';
        div.appendChild(pageDivHolder);

        // Prepare canvas using PDF page dimensions
        var canvas = document.createElement('canvas');
        var context = canvas.getContext('2d');
        canvas.width = pageDisplayWidth;
        canvas.height = pageDisplayHeight;
        pageDivHolder.appendChild(canvas);

       // Render PDF page into canvas context
       var renderContext = {
        canvasContext: context,
        viewport: viewport
       };
       page.render(renderContext).promise.then(callback);

       // Prepare and populate form elements layer
       var formDiv = document.createElement('div');
       pageDivHolder.appendChild(formDiv);
    
 //setupForm(formDiv, page, viewport);
  });
}


function pageLoaded() {
PDFJS.disableWorker = true;
PDFJS.workerSrc = "./pdf.worker.js";   // no i18n
PDFJS.getDocument({url: PDF_PATH}).then(function (pdf) {

        var canvas = document.createElement("canvas");
        canvas.setAttribute("id", "pageCanvas");
        canvas.setAttribute('style', "display:none");
        document.body.appendChild(canvas);

        // Rendering all pages starting from first
         var viewer = document.getElementById('viewer');
         var pageNumber = 1;
         renderPage(viewer, pdf, pageNumber++, function pageRenderingComplete() {
                if (pageNumber > pdf.numPages) {
                return; // All pages rendered
                }
                // Continue rendering of the next page
                renderPage(viewer, pdf, pageNumber++, pageRenderingComplete);
        });
});
}

document.addEventListener('DOMContentLoaded', function () {
  if (typeof PDFJS === 'undefined') {
    alert('Built version of PDF.js was not found.\n' +
          'Please run `gulp generic`.');
    return;
  }

and my index.html just loads the above js (form.js) and pdf.js and pdf.worker.js files

SERVER

This contains a servlet in which i have done the following

  1. Option to seek and read the file content from specific byte range by obtaining value from "Range" header in the request
  2. Have added Accept-Range:Bytes and Access-Control-Allow-Headers:Accept-Ranges values in response headers

Now I got struck in the following

1.Where to add "Range" header value?

2.How to send range request from client?

3.From where these calls were made?

4.Should I include viewer.html?

Please help me with this ! I'm collapsed :-(

Community
  • 1
  • 1
Tom Taylor
  • 3,344
  • 2
  • 38
  • 63
  • See https://github.com/joepie91/pdfy/blob/master/public_html/modules/download.php as a reference – async5 Nov 15 '16 at 22:23
  • I don't know about PHP @async5.. Sounds very new to me :-( Can you share me some other link please... – Tom Taylor Nov 15 '16 at 22:27
  • Your question is related to resumable download in java (not to PDF or PDF.js). See http://stackoverflow.com/questions/5011446/java-server-side-sending-file-with-resume-support/5013071#5013071 – async5 Nov 15 '16 at 22:28
  • Yes @async5 it is something like resumable download I guess since pdf.js has option for `progressive downloading` by specifying `Range` header value. I am not aware of where to set it in the client side... – Tom Taylor Nov 15 '16 at 22:30
  • FWIW client code looks reasonable. You don't have to do anything on client side. If HTTP range requests are working properly -- PDF.js will just use them. – async5 Nov 15 '16 at 22:31
  • My Server is capable of supporting range request. I am not sure from where should I invoke range request from my client.. – Tom Taylor Nov 15 '16 at 22:33
  • You can verify your server with [default PDF.js viewer](https://github.com/mozilla/pdf.js/releases/tag/v1.6.210) -- you shall see 206 responses in the devtools similar to the [demo viewer](http://mozilla.github.io/pdf.js/web/viewer.html). The demo viewer does not do anything different than your code (except using disableWorker=false). Please add link to the live demo/example on your server if you still have issues. – async5 Nov 15 '16 at 22:38
  • PDF.js does not use range requests for files less than 128kb – async5 Nov 15 '16 at 22:40
  • From where he is getting the pdf source in the sample @async5.. I couldn't find... Can you please help me with this.. – Tom Taylor Nov 15 '16 at 22:50
  • Tried with pdf greater than 128 kb size still it is getting entire file in a single request – Tom Taylor Nov 15 '16 at 22:56
  • Also tried with disableWorker=false/true this doesn't have any impact on range requests.. – Tom Taylor Nov 15 '16 at 22:56

1 Answers1

4

1.Where to add "Range" header value?

PDF.js detects if server returns "Accept-Ranges:Bytes" If server returns valid HTTP request headers (per spec), PDF.js (will abort main requests for platforms that does not allow incremental XHR and) will issue range requests.

2.How to send range request from client?

PDF.js does that automatically via XHR when it decides that server can handle range requests.

3.From where these calls were made?

See network.js file.

4.Should I include viewer.html?

No

Looks like currently the servlet that provides PDF data does not support valid HTTP range request protocol. Just setting "Accept-Ranges:Bytes" is not enough. See how it's implemented in PHP at or check previously answered question related to servlets.

Community
  • 1
  • 1
async5
  • 2,505
  • 1
  • 20
  • 27