6

Is there a way to read image files from url using only vanilla javascript? As context, I'm building a simple drag and drop image uploader and I think I've got the part where you read a literal file from a PC, but as for URLs how can I do it? Example: https://imgur.com/upload

I would like to be able to drag an image from google and have it read in the dropzone.

https://codepen.io/Ryenra/pen/JjoyPaq

function dropEv(e) {
    e.preventDefault();
    e.stopPropagation();
}

function dragOver(e) {
    document.getElementById('box').style = "opacity: 0.9;";
}

function dragLeave(e) {
    document.getElementById('box').style.removeProperty('opacity');
}


function receiveFile(e) {    
    let temp = e.dataTransfer.files;
    if(temp.length && temp[0].type.match(/image.*/)){
        document.getElementById('eText').textContent = temp[0].name;
    }else{
        alert('nv');
    }
}
html,body{
    height: 100%    
}

#content {
    height: 100%;
    display: flex;
    justify-content: center;
    align-items: center;
}


#box{
    width: 350px;
    height: 300px;   
    background: repeating-linear-gradient(
  -55deg,
  #222,
  #222 10px,
  #333 10px,
  #333 20px
);
    display: flex;
    justify-content: center;
    align-items: center;
}

#opa{
    width: 100%;
    height: 100%;
    border: 2px solid #000;
    display: flex;
    justify-content: center;
    align-items: center;
}



#inputFile{
    display: none;
}
<!DOCTYPE html>
<html lang="en">
<head>
    <link rel="stylesheet" href="style.css">
    <script src="script.js"></script>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
</head>
<body>
    <div id="content">           
            <div id="box" ondrop="dropEv(event),dragLeave(event),receiveFile(event)"  ondragover="dragOver(event),dropEv(event)" ondragleave="dragLeave(event)">
                <div id= "opa">
                        <p id="eText">Choose an image or drag it here!</p>
                </div>   
            </div>                  
    </div>
</body>
</html>
Hitesh Tripathi
  • 856
  • 1
  • 11
  • 23
Ryenra
  • 101
  • 4

2 Answers2

1

You can use the Fetch API like Nigel mentioned.

fetch('the image url', {mode: 'cors'})
  .then(res => res.blob())
  .then(blob => { /* use the blob */ })

fetch will return a response that you need to read as a Blob using res.blob()

Note: both fetch and res.blob return a promise which needs to be resolved using either .then() like in the example or async/await.

Blob and File are basically the same so you can probably use the Blob for whatever you need, but if you really need to, you can convert it into a File by using the File() constructor like this:

let file = new File([blob], "file name", {type: blob.type})

However because CORS exists, you might run into issues when trying to fetch images from arbitrary sites. Then you'll probably have to create a proxy server to fetch the images and add the 'Access-Control-Allow-Origin' header to the image with the value of either "*" (any domain) or "the domain your site is on".

Sorry for the plug, but I've recently wrote a guide on working with files on the client-side recently and it might prove useful for your project: Using Files in Client-Side JavaScript

0

In general, you can't. The Same-origin policy prevents browsers from reading the data from a different origin (unless CORS is used to grant permission).

You gave https://imgur.com/upload as an example, but they don't read the image using client-side JavaScript. The URL itself is sent to the server, then the requested from there by server-side code.

screenshot from Network request

Quentin
  • 914,110
  • 126
  • 1,211
  • 1,335