51

I try to upload an image to the Firebase storage from an URL (with ref().put(file))(www.example.com/img.jpg).

To do so i need a File or Blob, but whenever I try new File(url) it says "not enough arguments“…

EDIT: And I actually want to upload a whole directory of files, that’s why i can’t upload them via Console

Sam
  • 819
  • 2
  • 7
  • 17
  • 1
    Which environment are you running Javascript in? `File` can't take a URL and fetch it for you, you'll have to fetch it, read its data and create the `File` object with that data. – Lennholm May 19 '17 at 12:47
  • Yup, javascript. And you where right, thx so much for the fast answer ^^ – Sam May 19 '17 at 12:59

5 Answers5

91

Try using the fetch API. You can use it like so:

fetch('https://upload.wikimedia.org/wikipedia/commons/7/77/Delete_key1.jpg')
  .then(res => res.blob()) // Gets the response and returns it as a blob
  .then(blob => {
    // Here's where you get access to the blob
    // And you can use it for whatever you want
    // Like calling ref().put(blob)

    // Here, I use it to make an image appear on the page
    let objectURL = URL.createObjectURL(blob);
    let myImage = new Image();
    myImage.src = objectURL;
    document.getElementById('myImg').appendChild(myImage)
});
<div id="myImg"></div>

As of July 2022, the fetch API has about 97% browser support worldwide, with basically just IE missing it. You can get that to near 100% using a polyfill, which I recommend if you're still targeting IE.

James Kraus
  • 3,349
  • 20
  • 27
  • why use two .thens instead of just one which does res.blob at the beginning – stackers Sep 20 '19 at 21:39
  • 2
    res.blob() returns a promise, so we need to wait for it to resolve before accessing the contents: https://developer.mozilla.org/en-US/docs/Web/API/Body/blob – James Kraus Sep 23 '19 at 14:55
  • You will probalby get error "No 'Access-Control-Allow-Origin' header is present on the requested resource", if so you can use url proxy like proxy= https://cors-anywhere.herokuapp.com/ (or setup your own) then url = proxy + url, and use proxied url to fetch data. Here is a broad answer to this problem https://stackoverflow.com/a/43268098/9253363 – Karolius Sep 02 '20 at 14:26
4

@James answer is correct but it is not compatible with all browsers. You can try this jQuery solution :

$.get('blob:yourbloburl').then(function(data) {
  var blob = new Blob([data], { type: 'audio/wav' });
});
Sébastien Rosset
  • 1,481
  • 1
  • 10
  • 17
Ruan Carlos
  • 485
  • 5
  • 9
  • 13
    This is not a pure javascript solution but a jQuery one, you should definitely mention that in the answer. – Esko May 03 '19 at 07:28
1

It did not work until I added credentials

fetch(url, {
      headers: {
        "Content-Type": "application/octet-stream",
      },
      credentials: 'include'
 })
Petter Friberg
  • 21,252
  • 9
  • 60
  • 109
stanimirsp
  • 2,548
  • 2
  • 26
  • 36
1
async function url2blob(url) {
  try {
    const data = await fetch(url);
    const blob = await data.blob();
    await navigator.clipboard.write([
      new ClipboardItem({
        [blob.type]: blob
      })
    ]);
    console.log("Success.");
  } catch (err) {
    console.error(err.name, err.message);
  }
}
Stéphane Laurent
  • 75,186
  • 15
  • 119
  • 225
-3

If you are using homepage in package.json then ypu have to use:

CurrentUrl: http://localhost:3008/tempAppHomepageFromPackageJson/

const file: File = this.state.file;
const localUrlToFile = URL.createObjectURL(file);
const fileHash = localUrlToFile.split('/');
const objectUrl = location.href + fileHash[fileHash.length - 1];

objectUrl is the local url to file. For example to show in runtime you uploading file.

Second solution is (if you have no homepage in package.json):

const file: File = this.state.file;
const objectUrl = window.URL.createObjectURL(file);

Third solution (Not working in safari):

const file: File = this.state.file;
let reader = new FileReader();
reader.readAsDataURL(file);
const objectUrl = reader.result as string;

Enjoy ;)

voltdev
  • 260
  • 1
  • 4
  • 9