Skip to Content
Course content

98: The File API for Reading Local Files

Click on the "Edit" button in the top corner of the screen to edit your slide content.

When I first started working with the browser, I spent an entire afternoon trying to figure out why I couldn't just write a line of code like const data = fs.readFile('/Users/me/documents/notes.txt'). I was coming from a Node.js background, and I assumed the browser's JavaScript worked the same way. I kept getting errors, and I thought I was just missing a permission setting in my browser.

The Myth: JavaScript Can Access Any Local Path

A lot of learners assume that if they know the file path on their hard drive, they can tell the browser to go fetch it. You might think, "I'll just ask the user for the path to their configuration file and read it." Let's be very clear: you cannot do this.

If browsers allowed websites to read arbitrary files from your disk just by knowing the path, any random advertisement on a webpage could silently steal your .ssh/id_rsa key or your browser cookies. It would be a security nightmare. The browser is a sandbox; it's intentionally locked away from your filesystem to keep you safe.

The Reality: The User Must Hand You the File

To read a local file, the user has to explicitly "give" it to the browser. This happens through a specific user gesture—usually selecting a file via an <input type="file"> element or dragging and dropping a file into a designated area. Only then does the browser grant your code a File object, which is essentially a pointer to the data the user just authorized you to see.

Here is how we actually handle this. We don't look for a path; we listen for a change event on a file input:

<input type="file" id="file-picker" />
<div id="output"></div>

<script>
  const picker = document.getElementById('file-picker');
  const output = document.getElementById('output');

  picker.addEventListener('change', (event) => {
    // The 'files' property is an array-like list
    const selectedFile = event.target.files[0]; 
    
    if (selectedFile) {
      console.log(`User selected: ${selectedFile.name}`);
      // We have the file object, but we haven't read the content yet!
    }
  });
</script>

Decoding the File with FileReader

Having the File object is like having a locked book in your hand; you know the title and how heavy it is, but you can't read the pages yet. To actually get the text or binary data inside, you need the FileReader API.

The FileReader is asynchronous. You tell it how you want to read the file, you tell it which file to read, and then you wait for an event to trigger once the reading is finished. I personally find the event-based nature of FileReader a bit dated, but it's what we have to work with.

Let's say we're building a simple tool to preview a local CSV file for a budget report:

picker.addEventListener('change', (event) => {
  const file = event.target.files[0];
  if (!file) return;

  const reader = new FileReader();

  // This event fires when the file is successfully read
  reader.onload = (e) => {
    const content = e.target.result;
    output.textContent = `File content: ${content}`;
    
    // Now you could split by lines and commas to parse your CSV
    const rows = content.split('\n');
    console.log(`This CSV has ${rows.length} lines.`);
  };

  // This triggers the actual reading process
  reader.readAsText(file); 
});

Notice that I used readAsText(). If you were handling an image or a PDF, you'd use readAsDataURL() or readAsArrayBuffer() instead. Choosing the wrong method is a common trip-up, so always double-check what kind of data you're expecting.




📋 Practical Task

Build a Local Markdown-to-HTML Previewer

Your task is to create a small utility that allows a user to upload a .md (Markdown) text file from their computer and displays the raw text inside a <pre> tag on the page.

Requirements:

  • Create an <input type="file"> that only accepts .txt or .md files (use the accept attribute).
  • Implement a FileReader that reads the selected file as text.
  • Once the file is read, display the file's name in an <h2> and the actual content of the file inside a <pre> element.
  • Add a simple check: if the file is larger than 1MB, do not read it and instead alert the user that the file is too large.
Rating
0 0

There are no comments for now.

to be the first to leave a comment.