Search code examples
htmlclojurenoir

Open a client's plain text file on an HTML page


How could you use HTML to open a file on the client's machine as plaintext (i.e., a .cpp, .txt, or even a .html file)? I want to extract the plain textfile from the user's machine into an HTML <textarea>. Just FYI, I am using hiccup, clojure, and webnoir to generate the HTML and server so those are all other options to use to help the process along.


Solution

  • You have two main options: upload the file to your server to be served as HTML content or use HTML 5's File API. This question also addresses a few more options (like applets, enabling drag-and-drop with the File API, etc.)


    Upload the file

    1. Have the users choose the file using an <input type="file" .../> on one page
    2. Upload the file contents to your server.
    3. Redirect to a different page to show the file contents
    4. Serve the uploaded file's contents in a textarea on that page.

    Pros:

    • This method is pretty simple and straightforward.
    • You can scan the file and do some heavy processing on the server

    Cons:

    • Trips to the server can be time consuming.

    HTML 5 Solution

    1. Have the user choose the file using an <input type="file" .../>
    2. Instead of posting the contents, use JavaScript to load the file into your HTML 5 local storage (see code below)
    3. Use JavaScript to insert the contents of the file into your DOM.

    Pros:

    • No trip to the server (faster)

    Cons:

    • Any and all validation/processing must be done on the client side in JavaScript. This makes your client heavier and allows users to see/modify your code (which you might not need to care about).

    I grabbed this code snippet from this site, which has some good examples of using the File API:

    function onInitFs(fs) {
    
      fs.root.getFile('log.txt', {}, function(fileEntry) {
    
        // Get a File object representing the file,
        // then use FileReader to read its contents.
        fileEntry.file(function(file) {
           var reader = new FileReader();
    
           reader.onloadend = function(e) {
               // Do something with the contents, which are stored in 'this.result'
           };
    
           reader.readAsText(file);
        }, errorHandler);
    
      }, errorHandler);
    
    }
    
    window.requestFileSystem(window.TEMPORARY, 1024*1024, onInitFs, errorHandler);