[Total Noob] Download a pdf or any other file from Functions?

Hello,

Total noob here. I’m using an AJAX request to a Netlify Function. I’ve been trying to learn step by step how to do this. Anyone has any pointers on how can I return a file as a response?

ajax request —> netlify function —> response: [ blob ] http://server.com/file.pdf

I’ve been trying to get this done for days now and I keep running out of luck!

Any pointers are highly appreciated. I’m running a fairly basic netlify installation, nothing installed, really. Just the CLI and what comes with it.

Thanks.

Hi @MrAllanQuatermain

This is what I have come up with (there is likely other, possibly more elegant, solutions)

This will read a local file

const fs = require('fs')

exports.handler = async () => {

    const contents = fs.readFileSync('/path/to/img.jpg', {encoding: 'base64'});

    return {
        statusCode: 200,
        headers: {'Content-type' : 'image/jpeg'},
        body: contents,
        isBase64Encoded : true,
    }
}

This will read a URL

const fetch = require('node-fetch')

exports.handler = async (event, context) => {

    const img_url = "https://example.com/path/img.jpg"

    return fetch(img_url)
        .then(res => res.buffer())
        .then((buffer) => ({
            statusCode: 200,
            headers: {'Content-Type': 'image/jpeg'},
            isBase64Encoded: true,
            body: buffer.toString('base64'),
        }))
}

I have assumed an image/jpeg rather than having a way to check. I also have no error checking. But hopefully this gives you something to work with.

I must note that by “I came up with” I had help, particularly from javascript - Blob to Base64 in NodeJS without FileReader - Stack Overflow

1 Like

Here is another version, which accommodates different content-types

const fetch = require('node-fetch');
const fileType = require('file-type');

exports.handler = async () => {
 
  // Use a PDF
  const file = 'https://example.com/sample.pdf'
  // Or even an iamge
  //const file = 'https://example.com/sample.jpg'
  
  const response = await fetch(file);
  const status_code = response.status
  const content_type = response.headers.get('content-type')
  const buffer = await response.buffer();
  const type = await fileType.fromBuffer(buffer)

  return {
    statusCode: status_code,
    headers: {
      'Content-Type': content_type,
    },
    isBase64Encoded: true,
    body: buffer.toString('base64')
  }
}

Using node-fetch buffer as per docs.

Again, little checking (haven’t used response.ok to check it was OK)

1 Like