title: Upload PDF file to Express server
body: <p>I've built a basic browser form allowing users to upload a PDF file. I then want to send that file to an Express backend. It seems like this should be a pretty basic action, but I'm unfamiliar with the end-to-end process so I'm not sure which piece is failing. I've searched through a number of SO questions/answers, but haven't found any that provide a complete solution, and I haven't been able to cobble together a solution either.</p>
  
  <p><strong>Update:</strong> It looks like the file is getting to the server, but the encoding is messed up. My guess is that <code>FileReader.readAsText</code> is the wrong method to use. <code>FileReader.readAsBinaryString</code> got me a little closer, but still not quite right (and it's deprecated). <code>FileReader.readAsArrayBuffer</code> seems like potentially the way to go, but I'm not sure how to correctly handle the buffer in Express.</p>
  
  <p><strong>Client/Browser</strong></p>
  
  <p>The form is built in React and just uses an <code>onChange</code> handler on the input itself. When a file has been added, the handler reads the file, adds it to the form data and sends the post request to the server.</p>
  
  <pre><code>// React form
  &lt;input
    name="upload"
    onChange={this._handleUpload}
    type="file"
  /&gt;
  
  _handleUpload = (e) =&gt; {
    const { files, name } = e.target;
  
    // Read the file
    const reader = new FileReader();
    reader.onload = (e) =&gt; {
      const file = e.target.result;
  
      // Now that we have the file's contents, append to the form data.
      const formData = new FormData();
      formData.append('file', file);
      formData.append('type', name);
  
      axios
        .post('/upload', formData)
        .then(res =&gt; {
          // Handle the response...
        })
        .catch(err =&gt; console.log(err));
    };
  
    // Reading as text. Should this be something else?
    reader.readAsText(files[0]);
  }
  </code></pre>
  
  <p><strong>Express App</strong></p>
  
  <p>The express app uses <a href="https://www.npmjs.com/package/multer" rel="noreferrer">multer</a> middleware to process the upload:</p>
  
  <pre><code>const app = express();
  const upload = multer({});
  
  app.use(express.json());
  app.use(express.urlencoded({ extended: true }));
  app.use(cors());
  app.post('/upload', upload.any(), handleUpload);
  </code></pre>
  
  <p><strong>Middleware</strong></p>
  
  <p>Finally, I have my own middleware that gets the file from multer. I'm testing this piece by just writing the file I've received to disk. It has contents, but it's not a readable PDF file.</p>
  
  <pre><code>const handleUpload = (req, res, next) =&gt; {
    // The file shows up on req.body instead of req.file, per multer docs.
    const { file } = req.body;
  
    // File is written, but it's not a readable PDF.
    const tmp = fs.writeFileSync(
      path.join(__dirname, './test.pdf'),
      file,
    );
  }
  </code></pre>
  
  <p>Is there some piece that I'm getting obviously wrong here? eg: Do PDFs need to be handled in a special way? Any tips for where to focus my debugging?</p>