Giter VIP home page Giter VIP logo

js-file-download's People

Contributors

akshaybandivadekar avatar andyban avatar chrisdevereux avatar domino987 avatar exihuatl avatar fabianfrank avatar ffxsam avatar guoqchen1001 avatar jonashaag avatar jono20201 avatar kennethjiang avatar kindrowboat avatar localjo avatar lukaszflorczak avatar maxgraey avatar mikespitz avatar rmiller-fc avatar robmarshall avatar sakamossan avatar wkillerud avatar wuppious avatar ypresto 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  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

js-file-download's Issues

Downloading everything else than TXT leads to broken file (no server involved)

Hi,
My use case: in my React PWA a user can choose an attachment (of type TXT, JPG, PNG, PDF or ZIP).
The user should be able to download that attachment again too.
When I chose a TXT file, the downloaded file is correct. Every other type is broken (badly encoded?).

Here's my typescript code (for a ZIP file) stripped down to the bare minimum:
It starts with a simple input on my page:

<input  type="file"
             accept=".png,.jpg,.jpeg,.pdf,.txt,.zip"
             onChange={this.onFileSelected}/>

and this is the method that is called when a file is chosen:

    onFileSelected = (file) => {
        if (!file) { return; }
        const reader = new FileReader();
        reader.onloadend = () => {
             const fileData = reader.result as string;
             const ZIP_HEADER = 'data:application/x-zip-compressed;base64,';
             const dataIndex = fileData.indexOf(ZIP_HEADER);
             const binaryData = (dataIndex >= 0) ? fileData.substr(ZIP_HEADER.length + dataIndex) : fileData;

             // having that base64 encoded file content (without the header), now decode it
             // and feed it to fileDownload to save it as a zip file with the original name
             const fileDownload = require('js-file-download');
             fileDownload(atob(binaryData), file.name, 'application/x-zip-compressed');
        };
        reader.readAsDataURL(file);
   };

Result: while my initial Hello.zip file (a zip containing a text file 'hello.txt' containing just the word 'Hello') is 123 bytes, the resulting downloaded file is 137 bytes and it can't be opened.

Screenshot of both zip files opened with Notepad++: https://i.postimg.cc/2Shxpbvx/Screenshot-122.png The upper one is the original, good one. The lower one is the downloaded one. As you can see, there's something wrong with the two "XV,P," parts in the file.
Similar problems with PDF, PNG and JPG files. It works only correctly for TXT files (using TXT_HEADER = 'data:text/plain;base64,'; and as mimetype 'text/plain' then of course)

What is going wrong? Do I do something wrong? Or is js-file-download messing up?
Any help much appreciated.

Base64 Data

I try and send through base64 data and it just creates a file with the data as text.

Any help or advice?

Trying to download PDF file but Failed to load PDF

I try to download the file in react using Axios but it failing in both conditions.

add { responseType: 'blob' } to Axios and added fileDownload(res.data, fileName); but it gives Failed to load PDF document.

Removed { responseType: 'blob' } to Axios and added fileDownload(res.data.body, fileName); but its gives blank file with no content.
I am using Nodejs as backend with sending response in fs.createReadStream() and pipe()

License File?

Could you provide a license file? Hoping it's safe to assume the popular MIT license.

adding to bom option.

Hi!
i want to blob data include bom.
because i created csv file include garbled characters Japanese.

i want to this code to be changed like this.

module.exports = function(data, filename, mime, bom=null) {
    if (bom !== null) {
        data = [bom, data]
    } else {
        data = [data]
    }
    var blob = new Blob(data, {type: mime || 'application/octet-stream'});
    ...
}

// using sample.
var fileDownload = require('react-file-download');
var bom = new Uint8Array([0xEF, 0xBB, 0xBF]);
var mime = 'application/csv; charset=utf-8;';
fileDownload(data, 'filename.csv', mime, bom);

thanks.

Unable to download in Chrome on iOS

Hi team,

We use this package to implement CSV and ICS download functionality. It works fine on desktop and android devices(for all browsers) but for some reason, it does not work for Chrome on iOS(Safari works).
We wonder if anyone has experienced the same issue and could share the solution.

Thanks!

Some files are missed if send many requests together

Good Day,
I try to download many small files (<50 Kb). My JS sends 20 requests togther in order to download 20 files. I have checked that all 20 responses have been received correctly. I have also checked that for 20 files tempLinks in file-download.js have been clicked and then removed after timeout.
Problem is I can't download all requested files. More over each time I download different count of files 13/20, 16/20, 19/20. Rarely 20/20. I tried to increase timeout in file-download.js, but it didn't helped.
If I decrease count of simultaneous requests, situation becomes better. If count of simultaneous request = 1, I always receive 20 files correctly.
Please, help. Do you have any idea?

Does not work with iphone devices

Since ios7 devices require a hard touch to either download or open in new tab, this code ain't working for iPhone devices.
Click does not open the blob url file in a new tab.

File not downloading?

I just pulled the new version and trying to make this work :)

Currently it is downloading something with the given name however it does not contain anything and looks like this (windows):

image

I am supplying a url pointing to the file, am I doing this wrong? If so I think this would totally make sense to add to the component no?

Sample url (what I am providing in the data argument)
http://localhost/papaver/app/dashboard/uploads/patients/files/wizer-brochure-versie1%40dcc4c3031202bcfd765ae0c8fd5fc3d8%23IazEdDEYO7.pdf

When I log this to the console and click it it opens the correct file in a seperate tab ;)

Wrong react versions

The peer dependencies on react are wrong. React is using the format 15.x.x now, now 0.15.x.

File get renamed after download differently in every browser (colon).

When I trigger a download with a name containing a colon it gets renamed differently for every browser.
fileDownload(data, "file:name.json");

Chrome 53

file-name.json

IE 11

file_name.json

I know that colon cannot be saved in a file name but I expect file to be always named the same in every browser.

Wrong encoding?

let xhr = new XMLHttpRequest();
xhr.open('GET', 'http://domain.com/some.xlsx', true);

xhr.onload = function(e) {
  if (this.status === 200) {
    fileDownload(this.response, 'export.xlsx', 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet');
  }
};

xhr.send();

File downloaded, but wrong encoded, file opens as text inside xlsx -(

The file downloads but broken

I'm implementing a youtube video downloader using [ytdl-core][1] with Nodejs backend and Reactjs frontend. However, using ytdl-core library I'm able to send to the youtube video file to the frontend with this code block

    app.get('/download', (req, res) => {
        let { url, itag } = req.query;
        let id = ytdl.getURLVideoID(url);
    
        ytdl.getInfo(id, (err, info) => {
            if (err) {
                console.log(err);
                throw err;
            }
            else{
                let audioandvideo = ytdl.filterFormats(info.formats, 'audioandvideo');       
                let video = audioandvideo.filter(obj => obj.itag === itag);
    
                video = video[0]
    
                res.header('Content-Disposition', `attachment; filename="${info.title}.${video.container}"`);
                res.header('Content-Type', 'video/mp4');
    
                ytdl(url, {
                    format: video
                }).pipe(res); 
            }             
        })
    });

However, the file downloads correctly if I redirect the webpage to the route like this

window.location.href = `http://localhost:5000/download?url=${this.state.url}&itag=${itag}`;

This works fine and the video downloads correctly. But as it's a redirection I can't do that in a hosted site. So, I need to use axios to do this.

I did some research and found out some solutions. I tried with this library following the accepted answer here. It downloads the file to the client directory but the file won't play. This is the code block I used for that

      downloadVideo(itag){
    
        axios.get(`http://localhost:5000/download`, {
          params: { url: this.state.url, itag },
        })
        .then(response => {
          fileDownload(response.data, `video.mp4`);
        })
        .catch(err => console.log(err));
      }

As it's not working I tried another approach mentioned in the previously mentioned StackOverflow answer as well. It also downloads the file but doesn't work as well.

How can I get this fixed? What may be the reason my axios request doesn't work correctly?

Dependency on react

Hi, I just downloaded your project but it seems to also download react. Shouldn't the dependency in your package.json be replaced by peerDependencies?

This makes it so that it checks if the peer dependency is present, if not provide error but not always download react when installing your project.

See example of react-select package.json

Can't mock the module in TypeScript

Hey.

I'm having a very hard time mocking the fileDownload export. Not sure exactly how to do it correctly.

Error: Error: Uncaught [TypeError: js_file_download_1.default is not a function]

My attempt to mock.

// test.tsx

import fileDownload from 'js-file-download'

jest.mock('js-file-download', () => {
    return {
        _esModule: true,
        fileDownload: jest.fn(() => 'stuff'),
    }
})

window.URL.createObjectURL = jest.fn()
window.URL.revokeObjectURL = jest.fn()

test('returns the data when clicked', () => {
  
    // ... test implementation that renders a button and fires a click event.

    expect(fileDownload).toReturnWith('stuff')
})

old peer dependencies still on npm

I've freshly installed react-file-download and it says it has the wrong peer dependencies:

warning "[email protected]" has incorrect peer dependency "react@^0.14.7 || ^0.15.0".

Since the source code no longer has these dependencies, i can only imagine that the changes have not been published properly.

text split in columns with string having comma

When a long string is to be added into a column, the data gets split into multiple columns wherever there is a comma. I haven't been able to find any work around for this yet. I also din't find anywhere within the code if comma was used a delimiter.

Any suggestions would help!

Safari on Mac issue

Hello,
we are experiencing weird behaviour on Safari on Mac:
instead of file start to download - blob content opens up in new tab and looks like bunch of non-readable symbols.
Rest of browsers works just fine.

strange behavior when selecting text

Hi! I would like to know if someone has faced with this behavior before. The problem comes when I try to copy a text, it seems as if the strings have split in letters.

This is how I call the fileDownloaded:
fileDownload( Buffer.from(data, 'base64'), expedition.pdf );

Thank you in advance!!
Captura de pantalla 2020-05-29 a las 15 04 31

Importing in TypeScript

What is the proper way to import the module in typescript?
The definition file suggests that it's a default export, however, TypeScript interprets that as having module.default, which this module does not in fact have. With the current definition file, the only way to get typed and working function is this:

import * as fileDownload_ from 'js-file-download';
const fileDownload = fileDownload_ as any as typeof fileDownload_.default;

Using default import returns undefined.

import fileDownload from 'js-file-download';
fileDownload === undefined // true

Unable to open a downloaded epub file

This is in reference to this stackoverflow question

I am trying to download an epub file and I see the file being downloaded. But I am unable to open the file. I think it is corrupted or not saved to disk properly.

Here is my code -
const FileDownload = require('react-file-download');
export const handleDownload = (url, bookName) => {
axios.get(url).then((res) => { FileDownload(res.data, bookName+'.epub', "application/epub+zip");});}

I also tried FileDownload(res.data, bookName+'.epub', "application/zip")

Any help is appreciated. Thanks.

Remove "react" from the name and README

This package works great, but it doesn't really have anything to do with React. It just exports a function that you can use to download an object as a file to the browser. I suggest renaming it as just "file-download" or something similar, and removing references to "React" in the documentation, so that others who aren't using React don't get the impression that they can't use it.

ES6 import not working

When using js-file-download with an ES6 import it expects the default export to be in .default.
When importing like this:

import fileDownload from "js-file-download";

I get following error:

Uncaught (in promise) TypeError: js_file_download_1.default is not a function

This is probably some incompatibility between CommonJS and ES6 modules. There is a workaround, using the entire module as the function:

import * as fileDownload from "js-file-download";
...
fileDownload(response.data);

Safari

Unfortunately this plugin does not work with safari. Any plan to take a look on that?

Downloading several files in batch

I try to use this library in my React PWA for downloading a bunch of files like this: The user

  1. selects a number of items in a list and 2. presses an export button

The piece of typescript code that I use is this:

    confirmExport = () => {
        const fileDownload = require('js-file-download');
        for (const att of this.props.attesten) {
            if (this.state.selectedAttestIds.includes(att.id)) {
                fileDownload(att.certificate, `certificate_${att.id}.xml`);
            }
        }
    };

I experience that if the user eg. selects 20 items, the result is only 10 or 15 downloaded xml files.
If I add logging for each file, I see that each of the 20 files is mentioned, however some of them are apparently NOT downloaded. (and yes, their names are unique. It's not that one file overwrites another)
If I change the settings of Chrome to ask me where to save a file, it opens a popup for each of the 20 files and each of them is downloaded correctly. If I change the setting back to "Don't ask me where to save" I have the problem again.
This makes me think of some kind of race condition...
Any ideas?

ReferenceError: Blob is not defined

I get a ReferenceError: Blob is not defined. When I run the code below.
I am using NodeJS and Electron.

axios({
		method: 'get',
		url: props.url,
		responseType: 'blob'
	}).then((response) => {
		var filepath = path.resolve(global.sharedObj['outputPath'], props.filename);
		fileDownload(response.data, filepath);

getting undefined filename

Any idea why i am getting undefined when downloading the file as the file name?

const downloadGPX = () => {
    axios({
      method: 'GET',
      url: `https://www.strava.com/api/v3/routes/${props.data.contentfulRoutes.slug}/export_gpx`,
      headers: { Authorization: `Bearer ${stoken}` },
      responseType: 'blob',
    })
      .then((response) => {
        console.log(response.data);
        fileDownload((response.data, `${route.name}.gpx`));
      })
      .catch((err) => {
        console.log(err);
      });
  };

The ${route.name}.gpx is the contents of the file

Blob is not defined

I keep receiving the error message, that comes from the file "file-download.js" at line 3, whenever I try to run that line of code:

var arg = {
  data: "",
  fileName: "hey",
  fileType: "txt"
};
var fileDownload = require('js-file-download');
fileDownload(arg.data, arg.fileName + "." + arg.fileType);

export CSV encoding utf-8 issue

I did it but 'ı,ü,ö,ğ,ş' this characters looks like 'ı ü ö ÄŸ ÅŸ' in the CSV file.
Can anyone solve this problem?

Direct downloads from Google Cloud Storage and how to set up CORS

Leaving this here for posterity, I got slogged with this one.

In order to direct download files from GCS you need a couple of things:

  • A valid signed URL to your cloud storage object
  • A valid CORS configuration installed in your bucket

I am using the official google cloud storage php library to generate signed URLs: https://github.com/googleapis/google-cloud-php-storage so check their docs for that.

In order to install your cors configuration you'll need to install gsutil: https://cloud.google.com/storage/docs/gsutil and use the below gsutil cors command:

gsutil cors set path/to/cors.json your-bucket-name

with the contents of your cors.json file looking like this:

[
    {
      "origin": ["https://domain1.com/"],
      "method": ["GET"],
      "responseHeader": ["*"],
      "maxAgeSeconds": 3600
    },
    {
      "origin": ["https://www.domain.com/"],
      "method": ["GET"],
      "responseHeader": ["*"],
      "maxAgeSeconds": 3600
    },
    {
      "origin": ["https://staging.domain.com/"],
      "method": ["GET"],
      "responseHeader": ["*"],
      "maxAgeSeconds": 3600
    }
]

(It's a good idea to put all your dev and prod urls in there).

Then in your app, serve the signed url somehow and use axios and js-file-download to download the file as per the readme in this repo:

	axios.get(signedUrl, {
		responseType: 'blob',
	}).then(res => {
		fileDownload(res.data, filename)
	}).catch(error => reject(error))

ALSO

In my UI I have a loading spinner that relies on the promise provided by axios there, and that promise resolves too early - there is a lag between when the promise resolves and when the file download actually starts, meaning my UI says "all done!" and then nothing happens until the blob finishes downloading. To get around this, I pass a function in as the filename to the fileDownload call:

	}).then(res => {
		fileDownload(res.data, filename()) // <-- here

that function returns a string for the filename, but first it manually flicks the UI over to the next step. full example:

const loading = false
const filename = 'some-supplied-string.mp4'

function resolveFilename(){
    loading = false
    return filename
}

function downloadFile(){
    loading = true
    axios.get('/fetch-signed-url').then(response => {
        axios.get(response.data.signedUrl, {
            responseType: 'blob',
        }).then(response => {
            fileDownload(res.data, resolveFilename())
        })
    })
}

Hope that helps someone!

Using this package with Reactjs

I tried using this package with Reactjs and it doesn't seem to work.
It seems to just save an empty PDF without actually querying the API.

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.