Skip to content

Instantly share code, notes, and snippets.

@codejockie
Created October 5, 2021 18:25
Show Gist options
  • Save codejockie/7e82cf331111eab76ab4dbfe80975a15 to your computer and use it in GitHub Desktop.
Save codejockie/7e82cf331111eab76ab4dbfe80975a15 to your computer and use it in GitHub Desktop.
Download a file in JS
function download(fileUrl, filename) {
const a = document.createElement("a")
a.href = fileUrl
a.setAttribute("download", filename)
a.click()
}
// With Axios
import axios from "axios"
async function downloadFile(url, filename) {
const response = await axios({
url, // File URL
method: "GET",
responseType: "blob",
})
const file = window.URL.createObjectURL(new Blob([response.data]))
const docUrl = document.createElement("a")
docUrl.href = file
docUrl.setAttribute("download", filename)
// Optional
document.body.appendChild(docUrl)
docUrl.click()
}
@codejockie
Copy link
Author

const fs = require("fs")
const http = require("http")
const https = require("https")
const { basename } = require("path")
const { URL } = require("url")

/**
 * Download a resource from `url` to `dest`.
 * @param {string} url Valid URL to attempt download of resource
 * @param {string} dest Valid path to save the file.
 * @returns {Promise<void>} A promise indicating download completion status.
 */
function download(url, dest) {
  const uri = new URL(url)
  if (!dest) {
    dest = basename(uri.pathname)
  }
  const pkg = url.toLowerCase().startsWith("https:") ? https : http

  return new Promise((resolve, reject) => {
    // Check that file does not exist before hitting network
    fs.access(dest, fs.constants.F_OK, (err) => {
      if (err === null) reject("File already exists")

      const request = pkg.get(uri.href, (response) => {
        switch (response.statusCode) {
          case 200: {
            const fileWriteStream = fs.createWriteStream(dest, { flags: "wx" })
            fileWriteStream.on("finish", () => resolve())
            fileWriteStream.on("error", (err) => {
              fileWriteStream.close()
              if (err.code === "EEXIST") reject("File already exists")
              else fs.unlink(dest, () => reject(err.message)) // Delete temp file
            })
            response.pipe(fileWriteStream)
            break
          }
          case 301:
          case 302:
            // Recursively follow redirects, only a 200 will resolve.
            download(response.headers.location, dest).then(() => resolve())
            break

          default:
            reject(
              `Server responded with ${response.statusCode}: ${response.statusMessage}`
            )
            break
        }
      })

      request.on("error", (err) => {
        reject(err.message)
      })
    })
  })
}

module.exports = { download }

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment