Search code examples
javascriptbrowser-cachepdf.js

How can I cache the uploaded file of the user in my website, without any database


I'm making a pdf reader website using the pdfjs library, and I wanted to make something similar to this website https://pdfviewer.softgateon.net/ which also uses pdfjs, though it's too old, but a nice thing about that website is that when I upload my pdf file, and after I'm done reading it, I close my browser and then tomorrow when I open that website, the pdf is already there at the last page that I was reading, I wanted to make the same capability for my website, but I have no idea how it's done, my website is only made by javascript, and I uploaded it on github pages, https://smh6.github.io/PDFWIZ/

And how it works is that, you upload your file and then, I remove the home page HTML and then I add the HTML of the reading mode page, can I get that feature in my website too? it doesn't have any backend, it's pure javascript

Is it related to the host that I'm using or it can be done with javascript?


Solution

  • As said in comment, upon adding the PDF, store it in a clientside database, (like localforage), which will persistently store the PDF as a blob in storage, which then on next visit you can load it back then render it again.

    Online Example: https://localforage-pdf.glitch.me

    Fundamental Example:

    <!DOCTYPE html>
    <html lang="en">
      <head>
        <meta charset="utf-8" />
        <meta name="viewport" content="width=device-width, initial-scale=1" />
        <title></title>
        <script
          src="https://cdnjs.cloudflare.com/ajax/libs/localforage/1.10.0/localforage.min.js"
          integrity="sha512-+BMamP0e7wn39JGL8nKAZ3yAQT2dL5oaXWr4ZYlTGkKOaoXM/Yj7c4oy50Ngz5yoUutAG17flueD4F6QpTlPng=="
          crossorigin="anonymous"
          referrerpolicy="no-referrer"
        ></script>
      </head>
      <body>
        <div id="pdf"></div>
    
        <input type="file" onchange="loadPDF(this)" accept="application/pdf" />
    
        <button id="clearPDF">
          Remove PDF
        </button>
    
        <script>
          // clear and initial display
          document.getElementById("clearPDF").onclick = function() {
            localforage.removeItem("lastPDF");
            document.getElementById("pdf").style.display = "none";
          };
          document.getElementById("pdf").style.display = "none";
    
          // render the pdf object, if you use a diff lib implement it here
          const renderPDF = function(src) {
            const resource = (window.URL || window.webkitURL).createObjectURL(
              new Blob([src], { type: "application/pdf" })
            );
    
            const object = document.createElement("object");
            object.setAttribute("data", resource);
            object.setAttribute("type", "application/pdf");
            object.setAttribute("width", "500");
            object.setAttribute("height", "678");
    
            const iframe = document.createElement("iframe");
            iframe.setAttribute("src", resource);
            iframe.setAttribute("width", "500");
            iframe.setAttribute("height", "678");
            iframe.innerHTML = "<p>This browser does not support PDF!</p>";
    
            object.append(iframe);
    
            document.getElementById("pdf").replaceChildren(object);
    
            // show it
            document.getElementById("pdf").style.display = "block";
          };
    
          // load the PDF from file input, render then store in storage
          const loadPDF = elm => {
            const fr = new FileReader();
            fr.onload = () => {
              // render
              renderPDF(fr.result);
    
              // store
              localforage.setItem("lastPDF", fr.result);
            };
            fr.readAsArrayBuffer(elm.files[0]);
          };
    
          // load and render last stored pdf
          localforage.getItem("lastPDF", (err, value) => {
            if (err || !value) return;
            renderPDF(value);
          });
        </script>
      </body>
    </html>