2

I am currently working on a webapp which will be used to upload files after a resize. When I am working on localhost:3000, the resize process works like a charm, but when I am working on 192.168.0.5:3000 for example (or another domain), canvas.toDataURL returns an empty string instead of the base64 and the resize never ends. This issue only occurs when the brave shields are enabled, and the reason behind the blocked element is a cross site device-recognition.

What can I do for my canvas to be able to resize an image I am uploading to the browser and get it's dataURL and Blob, when I am not using localhost ?

The idea is to get an file from an input, resize it to 16MP via a Canva, and get the blob of this canvas to send to the backend. I have a PictureCompress function which will read the file with new FileReader() in order to get the base64 of this file. After that I am creating a new Image() and set it's src to my reader event.target.result (the b64) and, onload I am supposed to create the Canvas to resize the image via ctx.drawImage, get the new base64 via canvas.toDataURL and then the blob.
This process is perfectly working on my webapp when running it locally, but when I change the url to access my machine IP (I expect it to be the same on a domain name), it is no longer working. For example, there is a live version of this code on CodeBox and the issue seems to occurs.

EDIT :

  1. This issue only occurs when the url has a port (192.168.0.5:3000 is not working, but 192.168.0.5 is working). Why ?
  2. On firefox, the above fix does not work : Blocked http://192.168.0.13/ from extracting canvas data because no user input was detected.. Is it because it's not https ? To be continued ...
function Uploader(props) {
  function PictureCompress(file, callback) {
    const fileName = file.name;
    const reader = new FileReader();

    reader.readAsDataURL(file);
    reader.onerror = error => console.warn(error);
    reader.onload = event => {
      const img = new Image();
      img.name = fileName;
      img.onerror = error => console.warn(error);
      img.onload = e => {
        const imageOriginalWidth = e.target.width;
        const imageOriginalHeight = e.target.height;

        const hvRatio = imageOriginalWidth / imageOriginalHeight;
        const vhRatio = imageOriginalHeight / imageOriginalWidth;

        const imageHvRatio = 16000000 * hvRatio;
        const imageVhRatio = 16000000 * vhRatio;

        const newWidth = Math.sqrt(imageHvRatio);
        const newHeight = Math.sqrt(imageVhRatio);

        const canvas = document.createElement("canvas");
        canvas.width = newWidth;
        canvas.height = newHeight;

        const ctx = canvas.getContext("2d");
        ctx.drawImage(img, 0, 0, newWidth, newHeight);

        const base64 = canvas.toDataURL(file.type);
        console.log(base64, newWidth, newHeight, file.type);
        canvas.toBlob(
          blob => {
            console.log(blob);
            callback(blob, base64);
          },
          file.type,
          0.85
        );
      };
      img.src = event.target.result;
    };
  }
  function recursiveUpload(index, files) {
    if (index >= files.length) {
      return;
    }

    const file = files[index];
    PictureCompress(file, resizedFile => {
      resizedFile.name = file.name;
      resizedFile.lastModified = file.lastModified;
      //MY API CALL, NOT THE ISSUE
    });
  }

  return (
      <input type={"file"} onChange={event => recursiveUpload(0, event.target.files)} />
  );
}

Thank you for your help !

TBouder
  • 2,539
  • 1
  • 14
  • 29
  • 1
    I was having the exact same issue (on a very similar goal in my app ironically). The only exception being that the app works flawlessly in firefox, with a specified port. The issue is only present in Brave. As a temporary workaround, I've adjusted the browser settings to allow for functionality. It might be worth more tinkering with per site settings (whitelisting options maybe?). For example, I went into Brave settings->Shields->Device recognition, and select the option to 'Allow all device recognition attempts'. Then the app behavior is as expected. – None Feb 21 '20 at 07:03
  • @Rapid537 for the record, I don't have the brave issue when my domain name is set. With a PhysicalIP (192.xxx.x.x) the Brave Shields just block everything, but when I am using my dummy domain name, with SSL, I can use the canvas with no issues. Is it the same for you, or are you experiencing this issue with a setup domain name ? – TBouder Feb 21 '20 at 09:04
  • (not with a setup domain yet, still working in production version dockerized front/back apps pre-deployment testing) You comment //MY API CALL, NOT THE ISSUE, but have you tried specifying *HTTP://192.xxx.x.x* in your api call? (you probably have, but w/o seeing your actual api call in this post/sandbox, I just wanted to double check) Outside of that it could be related to CORS on your backend config (which we also cannot see here, so just a shot in the dark..) I'd like to compare what's working on my end and not working on yours, but w/o seeing more of the complete code it's hard to assume. – None Feb 22 '20 at 05:28

0 Answers0