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>

2 Answers 2

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

Sign up to request clarification or add additional context in comments.

Comments

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

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.