converting <svg> element to a file object in JavaScript [duplicate] - javascript

There's a File object in JavaScript. I want to instantiate one for testing purposes.
I have tried new File(), but I get an "Illegal constructor" error.
Is it possible to create a File object ?
File Object reference : https://developer.mozilla.org/en/DOM/File

According to the W3C File API specification, the File constructor requires 2 (or 3) parameters.
So to create a empty file do:
var f = new File([""], "filename");
The first argument is the data provided as an array of lines of text;
The second argument is the filename ;
The third argument looks like:
var f = new File([""], "filename.txt", {type: "text/plain", lastModified: date})
It works in FireFox, Chrome and Opera, but not in Safari or IE/Edge.

Now you can!
var parts = [
new Blob(['you construct a file...'], {type: 'text/plain'}),
' Same way as you do with blob',
new Uint16Array([33])
];
// Construct a file
var file = new File(parts, 'sample.txt', {
lastModified: new Date(0), // optional - default = now
type: "overide/mimetype" // optional - default = ''
});
var fr = new FileReader();
fr.onload = function(evt){
document.body.innerHTML = evt.target.result + "<br>Download " + file.name + "<br>type: "+file.type+"<br>last modified: "+ file.lastModifiedDate
}
fr.readAsText(file);

Update
BlobBuilder has been obsoleted see how you go using it, if you're using it for testing purposes.
Otherwise apply the below with migration strategies of going to Blob, such as the answers to this question.
Use a Blob instead
As an alternative there is a Blob that you can use in place of File as it is what File interface derives from as per W3C spec:
interface File : Blob {
readonly attribute DOMString name;
readonly attribute Date lastModifiedDate;
};
The File interface is based on Blob, inheriting blob functionality and expanding it to support files on the user's system.
Create the Blob
Using the BlobBuilder like this on an existing JavaScript method that takes a File to upload via XMLHttpRequest and supplying a Blob to it works fine like this:
var BlobBuilder = window.MozBlobBuilder || window.WebKitBlobBuilder;
var bb = new BlobBuilder();
var xhr = new XMLHttpRequest();
xhr.open('GET', 'http://jsfiddle.net/img/logo.png', true);
xhr.responseType = 'arraybuffer';
bb.append(this.response); // Note: not xhr.responseText
//at this point you have the equivalent of: new File()
var blob = bb.getBlob('image/png');
/* more setup code */
xhr.send(blob);
Extended example
The rest of the sample is up on jsFiddle in a more complete fashion but will not successfully upload as I can't expose the upload logic in a long term fashion.

Now it's possible and supported by all major browsers: https://developer.mozilla.org/en-US/docs/Web/API/File/File
var file = new File(["foo"], "foo.txt", {
type: "text/plain",
});

The idea ...To create a File object (api) in javaScript for images already present in the DOM :
<img src="../img/Products/fijRKjhudDjiokDhg1524164151.jpg">
var file = new File(['fijRKjhudDjiokDhg1524164151'],
'../img/Products/fijRKjhudDjiokDhg1524164151.jpg',
{type:'image/jpg'});
// created object file
console.log(file);
Don't do that ! ... (but I did it anyway)
-> the console give a result similar as an Object File :
File(0) {name: "fijRKjokDhgfsKtG1527053050.jpg", lastModified: 1527053530715, lastModifiedDate: Wed May 23 2018 07:32:10 GMT+0200 (Paris, Madrid (heure d’été)), webkitRelativePath: "", size: 0, …}
lastModified:1527053530715
lastModifiedDate:Wed May 23 2018 07:32:10 GMT+0200 (Paris, Madrid (heure d’été)) {}
name:"fijRKjokDhgfsKtG1527053050.jpg"
size:0
type:"image/jpg"
webkitRelativePath:""__proto__:File
But the size of the object is wrong ...
Why i need to do that ?
For example to retransmit
an image form already uploaded, during a product update, along with additional images added during the update

Because this is javascript and dynamic you could define your own class that matches the File interface and use that instead.
I had to do just that with dropzone.js because I wanted to simulate a file upload and it works on File objects.

Related

Converting a Blob object into a File, for Ms Edge

I have a Blob Object, which is an image and I am trying to convert into a file object, But it shows errors in MS edge version 41. I am using formdata in 1st two attempts for the same
Attempt 1
fd.set('file', blobObj, fileName);
return (fd.get('file'));
This resulted in an error
object doesn't support this property or method 'set'
Attempt 2
I replaced set with append and then I got this
object doesn't support this property or method 'get'
Attempt 3
I replaced formdata entirely with a new logic which looked like this
let fileObject = new File([u8arr], fileName, { type: mime });
and I got an error saying
object doesn't support this action
Is there any other method that can be used? Can I directly use blob as a file?
AFAIK, Your third approach seems to be working ,
Try once by hard-coding the mime type to "image/jpeg" / "image/png" and include the date modeified and then verify once
var fileInstance = new File([blob], "FileName",{type:"image/jpeg", lastModified:new Date()})
If you are displaying it in javascript you should use something like this:
var URL = window.URL || window.webkitURL;
var url_instance = URL.createObjectURL(blob);
var image_source = new Image();
image_source.src = url_instance;
document.body.appendChild(image_source);
A File object is a specific kind of a Blob, it's just missing the two properties: lastModifiedDate and name(file name property).
So, you could convert the blob object to file object using the following code:
var blobtoFile = function blobToFile(theBlob, fileName) {
//A Blob() is almost a File() - it's just missing the two properties below which we will add
theBlob.lastModifiedDate = new Date();
theBlob.name = fileName;
return theBlob;
}
var file = blobtoFile(blob, "test.png");
More detail information about using the above code, please check this sample.
Besides, please check the FormData Method Browser compatibility, from it we can see most of the methods support Microsoft Edge 44+(EdgeHTML 18+, more detail, please check this article).
So, if you want to use FormData set or get method, please try to upgrade the Windows version(Microsoft Edge is part of the operating system and can't be updated separately. It receives updates through Windows Update, like the rest of the operating system.). Otherwise, you could use a JavaScript Object to store the blob or file object.
Detail updated steps as below: Select Start > Settings > Update & Security > Windows Update , then select Check for updates and install any available updates.

How to create a modified copy of a File object in JavaScript?

Properties of files received from an <input type="file"> are read-only.
For example, the following attempt to re-write file.name would either fail silently or throw TypeError: Cannot assign to read only property 'name' of object '#<File>'.
<input onchange="onchange" type="file">
onchange = (event) => {
const file = event.target.files[0];
file.name = 'foo';
}
Attempting to create a copy via Object.assign({}, file) fails (creates an empty object).
So how does one clone a File object?
My solution lay in the File constructor:
https://developer.mozilla.org/en-US/docs/Web/API/File#Implementation_notes
Which itself is an extension of Blob:
https://developer.mozilla.org/en-US/docs/Web/API/Blob/Blob
let file = event.target.files[0];
if (this.props.distro) {
const name = 'new-name-here' + // Concat with file extension.
file.name.substring(file.name.lastIndexOf('.'));
// Instantiate copy of file, giving it new name.
file = new File([file], name, { type: file.type });
}
Note the first argument to File() must be an array, not simply the original file.
You can use FormData.prototype.append(), which also converts a Blob to a File object.
let file = event.target.files[0];
let data = new FormData();
data.append("file", file, file.name);
let _file = data.get("file");
A more cross browser solution
The accepted answer works for me too in modern browsers, but unfortunately it does not work in IE11, since IE11 does not support the File constructor.
However, IE11 does support the Blob constructor so it can be used as an alternative.
For example:
var newFile = new Blob([originalFile], {type: originalFile.type});
newFile.name = 'copy-of-'+originalFile.name;
newFile.lastModifiedDate = originalFile.lastModifiedDate;
Source: MSDN - How to create a file instannce using HTML 5 file API?

Loading a video file without input upload

I am incidently using react but the fact remains: when I put up a simple page with an input to upload a local file, if I console.log the actual file once it has been selected, here is what I get from the console:
File {name: "myfile.mp4", lastModified: 1474084788000, lastModifiedDate: Fri Sep 16 2016 23:59:48 GMT-0400 (EDT), webkitRelativePath: "", size: 27828905…}
lastModified: 1474084788000
lastModifiedDate: Fri Sep 16 2016 23:59:48 GMT-0400 (EDT)
name: "myfile.mp4"
size: 27828905
type: "video/mp4"
webkitRelativePath: ""
__proto__: File
And so the file loads in the video tags and I can watch it. (The code is below...)
Then, if I want to load the same file but from a hardcoded full path instead, like so: "file:///path/to/myfile.mp4", an error pops up This video file format is not supported. and what I get back from the console is the exact same path that I had previously hardcoded.
My question is how should one load a local file by using a hardcoded path instead of selecting a file from an input element?
OR
How to create an objectURL directly from a local path?
I've already tried to Blob the file before passing it on to the URL.createObjectURL function but, unless I did it something wrong, it didn't work out.
Render function code:
render() {
return (
<div>
<input type="file" ref="input" onChange={this.upload} />
<video ref="video" type="video/mp4" controls loop autoPlay width="720"></video>
<div ref="message"></div>
</div>
);
}
Functions:
processs = (file) => {
let fileURL = URL.createObjectURL(file);
this.refs.video.src = fileURL;
}
playFile = (event) => {
let file = event.target.files[0];
console.log(file);
//check if video can be played
if(this.refs.video.canPlayType(file.type) != ""){
this.processs(file);
} else {
this.refs.message.innerHTML = "This video file format is not supported."
}
};
Here is a working demo
Load Image or Video without Upload
Hope it helps
How to create an objectURL directly from a local path?
You can use XMLHttpRequest with responseType set to "blob". File inherits from Blob, you can pass returned Blob to your existing function which expects File object. See also Loading images from file with Javascript
var request = new XMLHttpRequest();
request.responseType = "blob";
request.open("GET", "file:///path/to/myfile.mp4");
request.onload = () => {
// do stuff with `request.response` : `Blob`
}
request.send();

javascript creating a file from URL

I'm using a 3rd party library which wants to load in a file via the HTML file system, as in:
<input id="fileupload" type="file" onchange="LoadAndDisplayFile(this.files[0])">
This works great, except I'd like to pass in a url to a file stored on the serverr rather than have the user upload a file.
I tried using:
var myFile = new File ("path/to/file");
with the hope that I'd then be able to pass myFile into LoadAndDisplayFile()
but I get the following error:
Uncaught TypeError: Failed to construct 'File': 2 arguments required, but only 1 present.
I'm sure this is a noob question, but what am I missing here?
You cannot create a File object only giving an URL to it.
The right method is to get the file through a Http request and read it, with something like this:
var blob = null
var xhr = new XMLHttpRequest()
xhr.open("GET", "path/to/file")
xhr.responseType = "blob"
xhr.onload = function()
{
blob = xhr.response
LoadAndDisplayFile(blob)
}
xhr.send()
I was dealing with same error and after spending time I created new File object using below code
new File(
[""],this.name,{
lastModified: 1605685839310,
lastModifiedDate: new Date(),
size: this.size,
type: "",
webkitRelativePath: ""
});

How to give a Blob uploaded as FormData a file name?

I am currently uploading images pasted from the clipboard with the following code:
// Turns out getAsFile will return a blob, not a file
var blob = event.clipboardData.items[0].getAsFile(),
form = new FormData(),
request = new XMLHttpRequest();
form.append("blob",blob);
request.open(
"POST",
"/upload",
true
);
request.send(form);
Turns out the uploaded form field with receive a name similar to this: Blob157fce71535b4f93ba92ac6053d81e3a
Is there any way to set this or receive this file name client side, without doing any server side communication?
For Chrome, Safari and Firefox, just use this:
form.append("blob", blob, filename);
(see MDN documentation)
Adding this here as it doesn't seem to be here.
Aside from the excellent solution of form.append("blob",blob, filename); you can also turn the blob into a File instance:
var blob = new Blob([JSON.stringify([0,1,2])], {type : 'application/json'});
var fileOfBlob = new File([blob], 'aFileName.json');
form.append("upload", fileOfBlob);
Since you're getting the data pasted to clipboard, there is no reliable way of knowing the origin of the file and its properties (including name).
Your best bet is to come up with a file naming scheme of your own and send along with the blob.
form.append("filename",getFileName());
form.append("blob",blob);
function getFileName() {
// logic to generate file names
}
That name looks derived from an object URL GUID. Do the following to get the object URL that the name was derived from.
var URL = self.URL || self.webkitURL || self;
var object_url = URL.createObjectURL(blob);
URL.revokeObjectURL(object_url);
object_url will be formatted as blob:{origin}{GUID} in Google Chrome and moz-filedata:{GUID} in Firefox. An origin is the protocol+host+non-standard port for the protocol. For example, blob:http://stackoverflow.com/e7bc644d-d174-4d5e-b85d-beeb89c17743 or blob:http://[::1]:123/15111656-e46c-411d-a697-a09d23ec9a99. You probably want to extract the GUID and strip any dashes.
Haven't tested it, but that should alert the blobs data url:
var blob = event.clipboardData.items[0].getAsFile(),
form = new FormData(),
request = new XMLHttpRequest();
var reader = new FileReader();
reader.onload = function(event) {
alert(event.target.result); // <-- data url
};
reader.readAsDataURL(blob);
It really depends on how the server on the other side is configured and with what modules for how it handles a blob post. You can try putting the desired name in the path for your post.
request.open(
"POST",
"/upload/myname.bmp",
true
);
Are you using Google App Engine?
You could use cookies (made with JavaScript) to maintain a relationship between filenames and the name received from the server.
When you are using Google Chrome you can use/abuse the Google Filesystem API for this. Here you can create a file with a specified name and write the content of a blob to it. Then you can return the result to the user.
I have not found a good way for Firefox yet; probably a small piece of Flash like downloadify is required to name a blob.
IE10 has a msSaveBlob() function in the BlobBuilder.
Maybe this is more for downloading a blob, but it is related.

Categories

Resources