Coder Social home page Coder Social logo

js-file-downloader's Introduction

APE Design


JS File Downloader

Version License

🌟Please remember to star this github repo if you like it. Thank you! ❤️

Introduction

JS File Downloader is a simple no dependency library you will be able to download file from browser and show downloading status.

Browser Compatibility

JS File Downloader supports all browsers that are [ES5-compliant] (http://kangax.github.io/compat-table/es5/) (IE8 and below are not supported).


Installing with package manager

With a package manager (recommended):

npm install js-file-downloader --save 

Basic usage

import JsFileDownloader from 'js-file-downloader';

const fileUrl = 'http://...';

new JsFileDownloader({ 
    url: fileUrl
  })
  .then(function () {
    // Called when download ended
  })
  .catch(function (error) {
    // Called when an error occurred
  });
  

Use without a package manager

Download this library from https://github.com/AleeeKoi/js-file-downloader/releases

<script src="/path/to/js-file-downloader.min.js"></script>
<script>
  // Then somewhere in your code
  new jsFileDownloader({ url: 'https://cdn.apedesign.net/github/logo.png' })
    .then(function () {
      // Called when download ended
    })
    .catch(function (error) {
      // Called when an error occurred
    });
</script>

Options:

process (for checking download status)

A function to call every time a process event is called. Function receive an Event Object as input.

function process (event) {
  if (!event.lengthComputable) return; // guard
  var downloadingPercentage = Math.floor(event.loaded / event.total * 100);
  // what to do ...
};

new JsFileDownloader({ 
  url: '...',
  process: process
})
  

onloadstart ('loadstart' event listener)

A function to call when a 'loadstart' event is triggered.

function onloadstart () {
  // what to do ...
}

new JsFileDownloader({ 
  url: '...',
  onloadstart
})
  

headers (of request)

If you need to customize request header data you can pass an array of objects like following example:

new JsFileDownloader({ 
  url: '...',
  headers: [
    { name: 'Authorization', value: 'Bearer ABC123...' }
  ]
})

filename

Setting this String you can force output file name

timeout (ms)

Integer value (default 40000) defining how much ms attend before stop download action.

autoStart

Boolean value (default true) to enable/disable automatically starting the download. When the value is true the constructor returns a Promise, however when it's set to false, the constructor doesn't return anything and the download can be started by calling the start() method on the object.

Example with autoStart set to true

new JsFileDownloader({ 
  url: '...',
  autoStart: true
})

Example with autoStart set to false

const download = new JsFileDownloader({ 
  url: '...',
  autoStart: false
});

download.start()
  .then(function(){
      // success 
  })
  .catch(function(error){
      // handle errors
  });

forceDesktopMode

Boolean value (default false) to force desktop mode even on mobile devices for downloading files.

new JsFileDownloader({ 
  url: '...',
  forceDesktopMode: true
})

withCredentials

This is a Boolean that indicates whether or not cross-site Access-Control requests should be made using credentials such as cookies, authorization headers or TLS client certificates. Setting withCredentials has no effect on same-site requests.

new JsFileDownloader({ 
  url: '...',
  withCredentials: true
})

method

The HTTP request method to use, such as "GET", "POST", "PUT", etc. (default "GET") Ignored for non-HTTP(S) URLs.

new JsFileDownloader({ 
  url: '...',
  method: 'POST'
})

nameCallback

You could pass a callback to customize final name, the function receive as 1st argument the name automatically extracted.

new JsFileDownloader({ 
  url: '...',
  nameCallback: function(name) {
    return 'i-am-prefix-' + name;
  }
})

contentType

Setting this property you can customize the content type in the heade request, default is 'application/x-www-form-urlencoded' If you set this property as false, the library doesn't set it.

new JsFileDownloader({ 
  url: '...',
  contentType: 'multipart/form-data; boundary=something' // or false to unset it
})

nativeFallbackOnError

By setting this property to true (default is false) when error occours the download will fallback to the default behavior opening a new tab.

new JsFileDownloader({ 
  url: '...',
  nativeFallbackOnError: true
})

body

By setting this property you can customize the body content sent with the request. Default value is null (nothing is sent), Document or BodyInit value can be set.

new JsFileDownloader({ 
  url: '...',
  body: 'The body as a string'
})

contentTypeDetermination

By setting this property the downloader will determine the content type automatically depending on the value.

value description
"header" Gets type from content-type response header.
"signature" Analyzes the first 4 bytes of the returned file and will check if that signature exists in the predetermined dict (You can override/merge this dict with the customFileSigantures property).
"full" Uses both methods from above but prefers "siganture".
false Type is not determined and the default is added, application/octet-stream.
new JsFileDownloader({ 
  url: '...',
  contentTypeDetermination: 'header'
})

customFileSignatures

By setting this value you can override/merge the predefined signature dict (src/signatures.js). The key represents the hex code of a file (for more information here) and the value should be in the format of a content type (e.g. application/pdf). Setting this value has only an affect when contentTypeDetermination is set to "full" or "signature".

new JsFileDownloader({ 
  url: '...',
  contentTypeDetermination: 'full', // must be set to "full" or "signature"
  customFileSignatures: {
    'FFFB':'audio/mpeg',
    'FFF3':'audio/mpeg',
    'FFF2':'audio/mpeg',
    '494433': 'audio/mpeg'
  }
})

Abort:

Setting autoStart option to false the process can be aborted calling the related method abort. The download promise is rejected, the reason can be customized passing is as the 1st param of the abort function.

const download = new JsFileDownloader({ 
  url: '...',
  autoStart: false
});

download.start()
  .catch(function(reason){
      // handle errors
  });

download.abort(/** reason */);

License

MIT

Copyright (c) 2019-present, Alessandro Pellizzari

apedesign.net

js-file-downloader's People

Contributors

aleeekoi avatar erichideyuki avatar lgdd avatar littlegraycells avatar marvin-kolja avatar mbaroukh avatar nnnaix avatar techieshark avatar tushinski avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar

js-file-downloader's Issues

Not downloading on chrome mobile

For whatever reason, this does not appear to work on chrome mobile on iOS. It seems to download, but nothing ends up in our files. I believe this used to work so possibly something changed on chrome. It works on safari. This is how we call the JsFileDownloader:

new JsFileDownloader({
    forceDesktopMode: true,
    withCredentials: true,
    nativeFallbackOnError: true,
    headers: [
      {
        name: "timezoneOffset",
        value: new Date().getTimezoneOffset().toString(),
      },
    ],
    url: process.env.REACT_APP_API_URL + `${endpoint}?${stringify(params)}`,

Cannot set body on POST request.

Hello!
Trying to get file, but i need to make a POST request with params.
A pdf file will be generated with params, that must be send in post request, like name and so on.

new JsFileDownloader({
        url: process.env.REACT_APP_API_URL + url,
        headers: [{ name: "authorization", value: `Bearer ${token}` }],
        method: "POST",
        withCredentials: true,
        filename: "NDA.pdf",
        contentType: "application/json;charset=UTF-8",
      }) //@ts-ignore
        .catch(function (error) {
          console.dir("download error", error);
         
        });

Can you add a body field for POST request ?

Error status code

I don't see any way to get the status code from the error message thrown. Use case = 401 (Unauthorized) refresh users token and try again.

Looking a bit more into it the exceptions just might not be working correctly, the lib attempts to use -

https://github.com/AleeeKoi/js-file-downloader/blob/master/src/exception.js

Which then throws -

Error: Downloader error: TypeError: Cannot set property 'message' of undefined
at XMLHttpRequest.request.onload (js-file-downloader.js:217)

Which prevents the error message from properly getting emitted out.

Add ability to provide 'onloadstart' callback

Hi! It looks like there's no ability to listen for 'loadstart' event.
I don't think it's a very important feature, but it can be necessary in some cases (and I ran into one of them).
It would be nice if someday you decide to add the option :)

Append filename with mime type

Hey, I was wondering if you ever thought about appending the filename with the correct ending (e.g .pdf) following the mime type returned from the server. I implemented something like that with js-file-download but this package doesn't have type declarations.

Here a snippet:

axios
  .get(url, {
    responseType: 'blob',
  })
  .then((response) => response.data)
  .then((blob) => {
    // fileDownload is the function of the js-file-download library
    // It accepts the following: 
    // data: string | ArrayBuffer | ArrayBufferView | Blob,
    // filename: string,
    // mime?: string,
    // bom?: string
    fileDownload(blob, generateFilename(filename), blob.type);
  })
  .catch((error) => {
    console.error(error);
    throw error;
  });

The library does support a custom mime and what I did is just using the one which the blob reflects. Would be cool to have some ability to turn this on automatically.

What are your thoughts? Let me know 😉

ReferenceError: document is not defined

Error code :

/home/elish/Desktop/nodejs/node_modules/js-file-downloader/dist/js-file-downloader.js:1236
var link = document.createElement('a');
^

ReferenceError: document is not defined

mobileDisabled is not used

There is a parameter mobileDisabled but it's not used anywhere in the code. Or did I miss something?

The code and doc would probably require clarification in regards to that parameter and forceDesktopMode, to clearly explain how to make it work on mobile.

For instance the doc mentions that mobileDisableddefaults to false, while it's true in the code. But anyhow this parameter is not used.

issue trying to download remote files

Your script is awesome for downloading files that are hosted in the same server or directory

however, I had CORS related issues since most of the files I have are stored inside buckets provided by Google Cloud Platform, with an entirely different url path.

Is there a way to accomplish that with JS or make adjustments to the script itself.

Thanks

and STAY SAFE

Doesn't work on mobile browsers

It's working fine with desktop browsers. But doesn't work on mobile browsers.

Do you have solution or any workaround for mobile browsers?

Thanks in advance.

Download files using HTTPS throw error on console

I am using the latest version of this package minified for an internal project of the company I work and I noticed that when using HTTPS and trying to download files in different formats it throws an error on the console.
vmconnect_C0xhse8b6L
But this only happens on the first try, on the next's one the download proceeds correctly and no errors are shown.
Our source code that this happen is something like this
vmconnect_OYNd3EWvOd
I enabled the nativeFallbackOnError to true and the error was
vmconnect_NpbZhz3keL
So I tried debugging this function and also the endpoint and it seems that after returning the file to download it cannot be read and the error.request.response is null and the responseText is filled with [Exception: DOMException: Failed to read the 'responseText' property from 'XMLHttpRequest': The value is only accessible if the object's 'responseType' is '' or 'text' (was 'arraybuffer').
vmconnect_ntIhnHOFTo

Fallback to new tab on CORS error

I am running into #8, but it would be nice if this lib could better handle the CORS issue and fallback to the new tab approach

And/or allow one to specifically trigger the new tab approach; similar to, but the opposite of forceDesktopMode

Issue downloading a large file

Hello and thanks for this great library.

I'm having issues with a specific file, with is a large video (3.1GB), and stored on Amazon S3.
It seems that the file is being downloaded, I can see the progress through the process callback.
Once the downloading is complete, the file is saved, but instead of the expected video file, there is a 4 bytes file, which is just a text file containing the string "null".

Any ideas?

Thanks,
Tom

Webpack imported module 0 is not defined

Hi, I'm creating a chrome extension and I got this error when I tried to import the library

Uncaught ReferenceError: js_file_downloader__WEBPACK_IMPORTED_MODULE_0__ is not defined

I'm tried to import using jsFileDownloader, JsFileDownloader and with curly braces but it didn't worked. How can I fix this?

Any support for passing cookies with request

Hi, I want to ask is there any support for sending cookies with the request just like we can do with the JS Fetch by adding credentials: 'include' or with the XMLHttpRequest just by adding request.withCredentials = true;.

Kindly can anyone help me with this?

error 406

I am trying to download a zip file from gitlab using your library but I am getting a 406 error.

What could be the problem?

onloadstart is request time or actual download start?

I have a case where I am downloading zip files compiled in real-time, which may require several seconds processing before server starts to output. In this case, I wanted to detect when the file actually starts to download, and I assumed I could do that with onloadstart event, but it seems this triggers as soon as the request is made? If so, perhaps it could be useful with ondownloadstart? Or am I missing something?

In the meantime, I am using the process() function to detect that e.loaded > 0 but this seems less optimal.

URL-encoded filenames not un-encoded

Our server returns url-encoded filenames in the Content-Disposition header for compatibility reasons (e.g. to support accented characters). If our header looks like this:

Content-Disposition: attachment; filename="MetLife%20MET%20US.xlsx"; filename*=UTF-8''MetLife%20MET%20US.xlsx

the library downloads the file as:

MetLife%20MET%20US.xlsx

It would be great if the library un-encoded the filenames maybe using decodeURIComponent().

File opens in new window

I don't use npm.
When the code runs, the download is successful, but the file opens in a new window, not on the device. I couldn't understand why. Is there something I missed?
File download URL https://firebasestorage.googleapis.com/...

.html
<script src="js/downloader/dist/js-file-downloader.min.js"></script>

.js
`function download() {
new jsFileDownloader({
url: filedownloadurls[index],
mobileDisabled: true,
filename: filenames[index],
process: process
})
.then(function () {
console.log("Successfull");
})
.catch(function (error) {
console.log("ERROR");
});
}

function process (event) {
if (!event.lengthComputable) return;
var downloadingPercentage = Math.floor(event.loaded / event.total * 100);
console.log(downloadingPercentage)
};`

Add possibility to cancel download

When downloading a large file, I show a progress bar with a cancel button in my UI.
Can you add a function to abort the download, i.e., call abort() on the underlying request object?

With this code, I can cancel the request, but the finally block is never being called, meaning the Promise never gets resolved.

async function downloadFile() {
  const activity = createActivity(props.file.fileName)
  try {
    const downloader = new JsFileDownloader({
      url: getUrlPath(props.file),
      timeout: 0,
      autoStart: false,
      process(event) {
        activity.determinate = event.lengthComputable
        if (!event.lengthComputable) return
        activity.update(event.loaded / event.total)
      },
    })
    activity.cancel = () => downloader.request.abort()
    await downloader.start()
  } finally {
    activity.remove()
  }
}

most common customFileSignatures should be built in, PDF & MP3 not working.

customFileSignatures: {
    'FFFB':'audio/mpeg',
    'FFF3':'audio/mpeg',
    'FFF2':'audio/mpeg',
    '494433': 'audio/mpeg'
  }

I tried PDF and MP3 and both don't work, it is hard to debug, I followed the docs of customFileSignatures but no successs.

I hope anyone can explain to me how we would add extra mime-types of other formats for example when they have the same hex as existing ones in the object already and objects only accept unique key.

createObjectURL

When trying to use it in a Cordova-electron app I get this error:
Uncaught (in promise) TypeError: Failed to execute 'createObjectURL' on 'URL': Overload resolution failed.
at t. (js-file-downloader.min.js:10)

(does not depend on the file type or server).

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.