Is it possible to use JavaScript to get an image URL into an <input type="file">
ready for submitting? Or to achieve a similar effect? Practically, I have the image at .jpg
and I'd like to "preload it" into a use registration form so it can be submitted with the form as if it was loaded from the disk using an input field.
The case scenario is user data obtained from an API that I want to use to populate an user registration form where one field is the user's avatar which the API hand over as a URL.
This is not about how to preview an image selected from disk using an input field!
Is it possible to use JavaScript to get an image URL into an <input type="file">
ready for submitting? Or to achieve a similar effect? Practically, I have the image at http://example./xxx/image.jpg
and I'd like to "preload it" into a use registration form so it can be submitted with the form as if it was loaded from the disk using an input field.
The case scenario is user data obtained from an API that I want to use to populate an user registration form where one field is the user's avatar which the API hand over as a URL.
This is not about how to preview an image selected from disk using an input field!
Share Improve this question edited Feb 16, 2018 at 11:24 lavirius asked Feb 15, 2018 at 23:08 laviriuslavirius 4771 gold badge5 silver badges15 bronze badges 2- Consider applying a different approach. You can put the url in a canvas then pass the raw content of that image to the server for saving. Please visit the link for additional information. permadi./2010/10/… – cjatstackoverflow Commented Feb 16, 2018 at 1:07
- Other simple approach would be to sending the image URL to the server and grab and process the image server side. I am just curious if there is a native or browser API method that I could not find. – lavirius Commented Feb 16, 2018 at 11:09
5 Answers
Reset to default 4This is now possible with vanilla JS
We can fetch the file in our content script, so no background script headaches, convert the file into a blob and create a file in the memory using the new File constructor.
After that, we can select the input tag using standard query selectors, create a Data Transfer, pass the file to the input tag, and dispatch the change event with bubbles sounds simple dun it.
Here is the code snippet:
// This function does the following
// 1. fetches the PDF resume from the url provided
// 2. creates a file object with the resume data
// 3. triggers the change event on the file input element
// 4. the file input element gets the file object
// 5. the file object is uploaded to the website
async function handleResumeInput(remoteResumeURL) {
const designFile = await createFile(remoteResumeURL);
const input = document.querySelector('input[type="file"]');
const dt = new DataTransfer();
dt.items.add(designFile);
input.files = dt.files;
const event = new Event("change", {
bubbles: !0,
});
input.dispatchEvent(event);
}
async function createFile(url) {
let response = await fetch(url);
let data = await response.blob();
let metadata = {
type: "image/png",
};
return new File([data], "app-logo.png", metadata);
}
This post explains it in details https://medium./@dev_agam/automate-file-upload-with-chrome-extension-7ee6989d58e9
Example using FileReader API. This load the image loaded in the File object in image html object.
<!DOCTYPE html>
<html>
<head>
<title>TODO supply a title</title>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
</head>
<body>
<div>
<input id="btnFile" type="file" accept="image/*" />
</div>
<div>
<img id="img" style="max-width: 100px" />
</div>
<script>
var btnFile = document.getElementById("btnFile");
//Register event on file selected or changed.
addEvents(btnFile, "change", function (event) {
if (event.target.files.length !== 0) {
var file = event.target.files[0];
//Check if the file is IMAGE.
if (file.type.match("image.*")) {
var fl = new FileReader();
//Add event to read the content file.
addEvents(fl, "load", function (evt) {
//alert(evt.target.result);
try {
//CONVERT ARRAY BUFFER TO BASE64 STRING.
var dataURL = evt.target.result;
document.getElementById("img").src = dataURL;
} catch (e) {
alert(e);
}
});
//Read the file as arraybuffer.
fl.readAsDataURL(file);
} else {
alert("Please select a IMAGE FILE");
}
}
});
function addEvents(obj, evtName, func) {
if (obj.addEventListener !== undefined && obj.addEventListener !== null) {
obj.addEventListener(evtName, func, false);
} else if (obj.attachEvent !== undefined && obj.attachEvent !== null) {
obj.attachEvent(evtName, func);
} else {
if (this.getAttribute("on" + evtName) !== undefined) {
obj["on" + evtName] = func;
} else {
obj[evtName] = func;
}
}
}
function removeEvents(obj, evtName, func) {
if (obj.removeEventListener !== undefined && obj.removeEventListener !== null) {
obj.removeEventListener(evtName, func, false);
} else if (obj.detachEvent !== undefined && obj.detachEvent !== null) {
obj.detachEvent(evtName, func);
} else {
if (this.getAttribute("on" + evtName) !== undefined) {
obj["on" + evtName] = null;
} else {
obj[evtName] = null;
}
}
}
</script>
</body>
</html>
It is not possible. As an alternative solution you can use an input[type="url"]
and then on submit create the file to upload with JavaScript:
async function getFileFromUrl(url, name, defaultType = 'image/png') {
const response = await fetch(url)
const data = await response.blob()
return new File([data], name, {
type: data.type || defaultType,
})
}
Or instead of using this function you can convert it as base64:
async function getBase64FromUrl(url) {
let reader = new FileReader();
const response = await fetch(url)
const data = await response.blob()
return await new Promise((resolve, reject) => {
reader.onload = () => resolve(reader.result);
reader.onerror = reject;
reader.readAsDataURL(data);
})
}
And upload the base64 string.
The value of an input type="file" is read-only programatically for security reasons, so no, it is not possible.
Reference Link: https://www.w3schools./jsref/prop_fileupload_value.asp
As Jahl said, it can't be done for security reasons, but as an alternative you can have a hidden input value and populate that. Display the image and have an option to submit a different image -- if no other is submitted, use the loaded avatar by default.