Home > OS >  How to process an image from another domain in JavaScript?
How to process an image from another domain in JavaScript?

Time:10-08

Is there any good way to drag and drop an image form a web page in another domain into my web page and then do some processing on the data?

I have tried a variety of methods, but every method I try seems to run into cross-origin related restrictions.

I can understand say, not running scripts from foreign servers.

But given the following I don't see how inspecting the image data poses any additional security concern.

  • The image is publicly available without any credentials.
  • The user can already see the image on the original site.
  • The user can already right click and save the image if they want, and after saving it, drop it into my web page and do the same processing. I just want to save them the step.
  • If I want to load the image into my web page and then draw it there, the browser displays the foreign image on my web page.
  • If I wanted to show the user an altered version of the image, I could still easily do so by just overlaying another transparent canvas on top of it, and drawing on that.
  • The fact that the browser won't let someone process the foreign image, doesn't stop someone from making a desktop application that could pull the image from the same URLs and do whatever they want with it.

So if I can already do all those things, how is it a security concern for my script to read the color data from the image? What bad things can possibly happen if I find out the color of a pixel at coordinate (55, 73) is red? What possible security attacks could result?

CodePudding user response:

No, I don't think there is a way to do it with javascript.

On this point:

The user can already right click and save the image if they want, and after saving it, drop it into my web page and do the same processing. I just want to save them the step.

you could do automatically download that image to your server and process the image on it.

CodePudding user response:

Create a dropzone element (I used a element but you can create a different element):

<main></main>
<script>
  const dropzone = document.querySelector('main');
</script>

Give the dropzone a dashed border style:

<style>
  main {
    border: 1px border lightgray;
    width: 100px;
    height: 100px;
  }
</style>

Highlight the dropzone when the dragenter event is fired (image is dragged over the dropzone):

<style>
  .active {
    border: 1px dashed black;
  }
</style>

<script>
  // ...
  dropzone.addEventListener('dragenter', event => {
    event.preventDefault();
    dropzone.classList.add('active');
  });

event.preventDefault() is necessary or else the image will be opened from your local file explorer.

Remove the dropzone highlight when the dragleave event is fired (image is no longer dragged over the dropzone):

<script>
  // ...
  dropzone.addEventListener('dragleave', event => {
    event.preventDefault();
    dropzone.classList.remove('active');
  });
</script>

It’s necessary to handle the dragover event before drop happens:

<script>
  // ...
  dropzone.addEventListener('dragover', event => {
    event.preventDefault();
  });
</script>

Now handle the drop event (when the image is released inside the dropzone):

<script>
  // ...
  dropzone.addEventListener('drop', event => {
    event.preventDefault();
    dropzone.classList.remove('active');

    const file = event.dataTransfer.files[0];
    const reader = new FileReader();
    reader.readAsDataURL(file);

    reader.addEventListener('loadend', () => {
      const img = document.createElement('img');
      img.src = reader.result;
      dropzone.append(img);
    });
  });
</script>
  • Related