Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to check whether it is a blob url using javascript

I have a situation where I am converting blobURL to base64 dataURLs, but I want to do this only if url is a blobURL.

So is there any way to check whether it is valid blob url?

my blob url - blob:http://192.168.0.136/85017e84-0f2d-4791-b563-240794abdcbf

like image 327
Arjun Avatar asked Dec 18 '22 00:12

Arjun


1 Answers

You are facing an x-y problem.

You absolutely don't need to check if your blobURI is a valid one, because you absolutely don't need to use the blobURI in order to create a base64 version of the Blob it's pointing to.

The only way to do it is to fetch the Blob and this means creating a copy of its data in memory for no-good.

What you need is a way to retrieve this Blob.

There is unfortunately no official way to do so with the web APIs, but it's not that hard to make it ourselves:

We simply have to overwrite the default URL.createObjectURL method in order to map the passed Blob in a dictionnary using the blobURI as key:

(() => {
  // overrides URL methods to be able to retrieve the original blobs later on
  const old_create = URL.createObjectURL;
  const old_revoke = URL.revokeObjectURL;
  Object.defineProperty(URL, 'createObjectURL', {
    get: () => storeAndCreate
  });
  Object.defineProperty(URL, 'revokeObjectURL', {
    get: () => forgetAndRevoke
  });
  Object.defineProperty(URL, 'getBlobFromObjectURL', {
    get: () => getBlob
  });
  const dict = {};

  function storeAndCreate(blob) {
    var url = old_create(blob); // let it throw if it has to
    dict[url] = blob;
    return url
  }

  function forgetAndRevoke(url) {
    old_revoke(url);
    // some checks just because it's what the question titel asks for, and well to avoid deleting bad things
    try {
      if(new URL(url).protocol === 'blob:')
        delete dict[url];
    }catch(e){} // avoided deleting some bad thing ;)
  }

  function getBlob(url) {
    return dict[url];
  }
})();

// a few example uses

const blob = new Blob(['foo bar']);
// first normal use everyhting is alive
const url = URL.createObjectURL(blob);
const retrieved = URL.getBlobFromObjectURL(url);
console.log('retrieved: ', retrieved);
console.log('is same object: ', retrieved === blob);

// a revoked URL, of no use anymore
const revoked = URL.createObjectURL(blob);
URL.revokeObjectURL(revoked);
console.log('revoked: ', URL.getBlobFromObjectURL(revoked));

// an https:// URL
console.log('https: ', URL.getBlobFromObjectURL(location.href));

PS: for the ones concerned about the case a Blob might be closed (e.g user provided file has been deleted from disk) then simply listen for the onerror event of the FileReader you'd use in next step.

like image 70
Kaiido Avatar answered Jan 04 '23 19:01

Kaiido