Skip to content

PDF.js Read Only is an additional readonly mode for PDF.js (https://mozilla.github.io/pdf.js)

Notifications You must be signed in to change notification settings

latuminggi/pdf.js_readonly

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

41 Commits
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

PDF.js Read Only

PDF.js Read Only is an additional readonly mode for PDF.js, a Portable Document Format (PDF) viewer that is built with HTML5 which is community-driven and supported by Mozilla.

Its purpose to make PDF.js viewer to be readonly mode, including disable right click on mouse (context menu) and several hotkeys (keyboard shortcut) such as:

  • Ctrl + C (Copy Text)
  • Ctrl + O (Open PDF)
  • Ctrl + P (Print PDF)
  • Ctrl + S (Save PDF)
  • PrtSc      (Print Screen) (experimental)

Demo

A. Desktop
  1. PDF.js without read only  /generic/web/viewer.html
  2. If using PDF.js Read Only /generic/web/viewer_readonly.html
B. Mobile
  1. PDF.js without read only  /mobile-viewer/viewer.html
  2. If using PDF.js Read Only /mobile-viewer/viewer_readonly.html
C. Test
  1. PDF.js iframe read only    /test/iframe_readonly.html
  2. PDF.js mobile responsive /test/mobile_responsive.html
  3. PDF.js desktop mobile     /test/desktop_mobile.html

How To Use

A. Desktop

    Support Password Protected PDF

  1. /generic/web/viewer_readonly.html
    adjustment in viewer_readonly.html

    <!-- PDF.js Read Only Adjustment -->
    <!-- <script src="viewer.js"></script> --> <!-- you need to comment or remove this line -->
    <script src="//ajax.googleapis.com/ajax/libs/jquery/1.12.2/jquery.min.js"></script> <!-- adjust your jquery if necessary -->
    <script src="../../js/pdf.js_readonly.js"></script> <!-- adjust path to pdf.js_readonly.js -->
  2. /js/pdf.js_readonly.js
    adjustment in pdf.js_readonly.js

    // Read Only Preferences
    var disableRghtClck = true; // Disable Right Click,   value: true || false
    var disableCopyText = true; // Disable Copy Text,     value: true || false
    var disableOpenFile = true; // Disable Open PDF,      value: true || false
    var disablePrintPdf = true; // Disable Print PDF,     value: true || false
    var disableDownload = true; // Disable Save PDF,      value: true || false
    var disablePresents = true; // Disable Presentation,  value: true || false
    var disablePrntScrn = true; // Disable Print Screen,  value: true || false (experimental)
    
    // Load Specific viewer.js
    if ( disablePrintPdf ) {
      $.getScript( '../../js/viewer_noprint.js' ); // Adjust path to viewer_noprint.js if necessary
    } else {
      $.getScript( 'viewer.js' );  // Adjust path to viewer.js if necessary
    }
  3. /js/viewer_noprint.js
    modification from viewer.js

    /*  Modified for PDF.js Read Only
     *  To disable print overlay
     */
    /* window.addEventListener("keydown", function (event) {
      if (event.keyCode === 80 && (event.ctrlKey || event.metaKey) && !event.altKey && (!event.shiftKey || window.chrome || window.opera)) {
        window.print();
        event.preventDefault();
    
        if (event.stopImmediatePropagation) {
          event.stopImmediatePropagation();
        } else {
          event.stopPropagation();
        }
      }
    }, true); */

    Note: If you want to create viewer_noprint.js on your own from viewer.js file of your current PDF.js version, make sure those lines above (or some codes like that) are commented.

  4. /js/viewer_noprint.js

    • to protect PDF file source
    // value: "compressed.tracemonkey-pldi-09.pdf",
    /*  Modified for PDF.js Read Only
     *  It's better to NOT having .PDF extension in the end of file name
     *  This can avoid like IDM to sniff PDF file type automatically download
     *  You also can protect PDF file source from direct access using .htaccess
     *  Or you can never reveal its original file name such as encoding it first!
     */
    value: "compressed.tracemonkey-pldi-09",
    • to allow access PDF file from different domain
    const HOSTED_VIEWER_ORIGINS = ["null", "http://mozilla.github.io", "https://mozilla.github.io", "https://yourdomain.here"];

    and makesure the PDF file webserver has HTTP Header Access-Control-Allow-Origin, allowing PDF.js viewer domain

    Access-Control-Allow-Origin: http(s)://yourPDFjsViewerDomain.here
  5. /generic/web/viewer_readonly.html
    adjustment in viewer_readonly.html for custom progress document loading

    <!-- PDF.js Read Only Adjustment --> 
    <!-- Custom Progress Document Loading --> 
    <div id="customProgress" style="text-align:center;background:#FDFDFB;min-height:95vh">
      <img src="https://latuminggi.github.io/pdf.js_readonly/img/documentLoading.gif" /> 
    </div> 

    including adjustment in /js/viewer_noprint.js as you can see on this commit diff

  6. /generic/web/viewer_readonly.html
    to access file from query string (directly from URL)

    /generic/web/viewer_readonly.html?file={filename.pdf}

    For example: /generic/web/viewer_readonly.html?file=compressed.tracemonkey-pldi-09.pdf

    /generic/web/viewer_readonly.html?file={filename}

    For example: /generic/web/viewer_readonly.html?file=compressed.tracemonkey-pldi-09

    /generic/web/viewer_readonly.html?file={http(s)://example.com/filename(.pdf)}

    For example: /generic/web/viewer_readonly.html?file=https://latuminggi.github.io/pdf.js_readonly/generic/web/compressed.tracemonkey-pldi-09

B. Mobile

    NO Support for Password Protected PDF

  1. /mobile-viewer/viewer_readonly.html
    adjustment in viewer_readonly.html

    <!-- PDF.js Read Only Adjustment -->
    <!-- <script src="viewer.js"></script> --> <!-- you need to comment or remove this line -->
    <script src="viewer_mod.js"></script> <!-- adjust path to viewer_mod.js -->
    <script src="//ajax.googleapis.com/ajax/libs/jquery/1.12.2/jquery.min.js"></script> <!-- adjust your jquery if necessary -->
    <script src="../js/pdf.js_mobile_readonly.js"></script> <!-- adjust path to pdf.js_mobile_readonly.js -->

    Note: if you want to enable cache canvas on mobile viewer, you can adjust these lines

    <!-- PDF.js Read Only Adjustment -->
    <!-- <script src="build/pdf.min.js"></script> --> <!-- use pdf(.min).js to enable cache canvas on mobile -->
    <script src="build/pdf_mod.min.js"></script> <!-- use pdf_mod(.min).js to disable cache canvas on mobile -->

    and if you want to access PDF file from different domain, makesure the PDF file webserver has HTTP Header Access-Control-Allow-Origin, allowing PDF.js viewer domain

    Access-Control-Allow-Origin: http(s)://yourPDFjsViewerDomain.here
  2. /js/pdf.js_mobile_readonly.js
    adjustment in pdf.js_mobile_readonly.js

    // Read Only Preferences
    var disableRghtClck = true; // Disable Right Click,   value: true || false
    var disableCopyText = true; // Disable Copy Text,     value: true || false
    var disableOpenFile = true; // Disable Open PDF,      value: true || false
    var disablePrintPdf = true; // Disable Print PDF,     value: true || false
    var disableDownload = true; // Disable Save PDF,      value: true || false
    var disablePrntScrn = true; // Disable Print Screen,  value: true || false (experimental)
  3. /mobile-viewer/viewer_mod.js
    modification from viewer.js
    there are 2 differences

    • first: To enable PDF large image size
    /*  Modified for PDF.js Read Only
     *  To enable PDF large image size
     */
    // const MAX_IMAGE_SIZE = 1024 * 1024; // Limited Max Image Size
    const MAX_IMAGE_SIZE = false; // Unlimited Max Image Size
    • second: To enable get query string of file or using default PDF file
    /*  Modified for PDF.js Read Only
     *  To enable get query string of file
     *  How can I get query string values in JavaScript? https://stackoverflow.com/a/901144/17754812
     */
    function getParameterByName(name, url = window.location.href) {
      name = name.replace(/[\[\]]/g, '\\$&');
      var regex   = new RegExp('[?&]' + name + '(=([^&#]*)|&|#|$)'),
          results = regex.exec(url);
      if (!results) return null;
      if (!results[2]) return '';
      return decodeURIComponent(results[2].replace(/\+/g, ' '));
    }
    
    /*  Modified for PDF.js Read Only
     *  To get query string of file or using default PDF file
     */
    // const DEFAULT_URL = "web/compressed.tracemonkey-pldi-09.pdf";
    // Get PDF file whether from "DEFAULT_URL" or "file" query string
    var file = getParameterByName('file');
    const DEFAULT_URL = (file === null || file === "") ? "web/compressed.tracemonkey-pldi-09" : file;

    Note: If you want to create viewer_mod.js on your own from viewer.js file of your current PDF.js version, make sure those lines above (or some codes like that) are adjusted.

  4. /mobile-viewer/build/pdf_mod.js
    modification from pdf.js

    if (this.cache[id] !== undefined) {
      /*  Modified for PDF.js Read Only
       *  To disable cache canvas on mobile
       */
      /* canvasEntry = this.cache[id]; */
      canvasEntry = this.canvasFactory.create(width, height);
      this.canvasFactory.reset(canvasEntry, width, height);
      canvasEntry.context.setTransform(1, 0, 0, 1, 0, 0);
    }

    Note: If you want to create pdf_mod.js on your own from pdf.js file of your current PDF.js version, make sure those lines above (or some codes like that) are adjusted.

  5. /mobile-viewer/viewer_readonly.html
    adjustment in viewer_readonly.html for custom progress document loading

    <!-- PDF.js Read Only Adjustment --> 
    <!-- Custom Progress Document Loading --> 
    <div id="customProgress" style="text-align:center;background:#FFF;min-height:95vh"> 
      <img src="https://latuminggi.github.io/pdf.js_readonly/img/documentLoadingMobile.gif" width="100%" /> 
    </div> 

    including adjustment in /mobile-viewer/viewer_mod.js as you can see on this commit diff

  6. /mobile-viewer/viewer_readonly.html
    to access file from query string (directly from URL)

    /mobile-viewer/viewer_readonly.html?file=path_to/{filename.pdf}

    For example: /mobile-viewer/viewer_readonly.html?file=web/compressed.tracemonkey-pldi-09.pdf

    /mobile-viewer/viewer_readonly.html?file=path_to/{filename}

    For example: /mobile-viewer/viewer_readonly.html?file=web/compressed.tracemonkey-pldi-09

    /mobile-viewer/viewer_readonly.html?file={http(s)://example.com/filename(.pdf)}

    For example: /mobile-viewer/viewer_readonly.html?file=https://latuminggi.github.io/pdf.js_readonly/generic/web/compressed.tracemonkey-pldi-09

How To Protect PDF file(s) from Direct Access

A. Apache
RewriteEngine on 
# only allow from following domain(s):
RewriteCond %{HTTP_REFERER} !^http://(www\.)?example.com*$ [NC] 
RewriteRule \.(pdf)$ - [F]
B. Nginx
server {
  ...

  location ~* \.(pdf)$ {
    # only allow from following domain(s):
    valid_referers example.com www.example.com;

    if ($invalid_referer) {
      return 403;
    }
  }

  ...
}
C. PHP
<?php
$file = '/path/to/file.pdf';
// only allow if specific cookie(s) available, for example:
if ( isset( $_COOKIE['yourCookie'] ) && $_COOKIE['yourCookie'] === 'yourCookieValue' ) {
  // only allow from following domain(s), for example:
  if ( isset( $_SERVER['HTTP_REFERER'] ) && strpos( $_SERVER['HTTP_REFERER'], 'example.com' ) ) {
    if ( file_exists($file) ) {
      header('Access-Control-Allow-Origin: http(s)://example.com');
      /*  use HTTP header Content-Type application/octet-stream instead application/pdf
       *  this can avoid like IDM to sniff PDF file with mime type application/pdf
       *  and makesure the URL you create does NOT have .pdf extension in the end 
       */
      header('Content-Type: application/octet-stream');
      header('Content-Length: '. filesize($file));
      header('Cache-Control: no-cache');
      header('Pragma: no-cache');
      readfile($file);
      exit;
    }
  }
}

About

PDF.js Read Only is an additional readonly mode for PDF.js (https://mozilla.github.io/pdf.js)

Resources

Stars

Watchers

Forks