How can I serialize an input File object to JSON?
Asked Answered
M

8

64

I want to convert an HTML input file to a JSON string like this:

var jsonString = JSON.stringify(file);
console.log( file );
console.log( jsonString );

Now, in my Firebug it logs as:

File { size=360195, type="image/jpeg", name="xyz.jpg", mehr...} 
Object {}

Why is the jsonString empty?

Background info: I want to send the file-reference with JSONP to another PHP server.

Additional Information: I want to convert only the file-pointer (reference) to a string, to send it via GET.

Malapropism answered 10/6, 2014 at 10:21 Comment(0)
S
32

It is not possible to directly convert a File object into JSON using JSON.stringify in Chrome, Firefox and Safari.

You can make a work around to convert File object to string using JSON.stringify

Ex:

// get File Object  
var fileObject = getFile();

// reCreate new Object and set File Data into it
var newObject  = {
   'lastModified'     : fileObject.lastModified,
   'lastModifiedDate' : fileObject.lastModifiedDate,
   'name'             : fileObject.name,
   'size'             : fileObject.size,
   'type'             : fileObject.type
};  
 
// then use JSON.stringify on new object
JSON.stringify(newObject);

You can also add the toJSON() behavior to your File object

EX:

// get File Object  
var fileObject = getFile();

// implement toJSON() behavior  
fileObject.toJSON = function() { return {
   'lastModified'     : myFile.lastModified,
   'lastModifiedDate' : myFile.lastModifiedDate,
   'name'             : myFile.name,
   'size'             : myFile.size,
   'type'             : myFile.type 
};}  
 
// then use JSON.stringify on File object
JSON.stringify(fileObject);

Note: send a File Object to server using the POST HTTP method.

Switch answered 26/3, 2015 at 14:36 Comment(7)
Actually, in Chrome you cannot stringify a File object either.Make
yes, Now I had test JSON.stringify with File Object in chrome and does not work. But I had test it when I answer this question was workSwitch
Uh... what? The File API was not meant to be convertible to a String. See: #19119540Moonlight
@williamle8300 your miss the part of Question that say he want to send File Object as JSON request to PHP server So that he want to Stringify File Object. the Question link which you put it, ask for another case also the accept answer say: (you can't serialize File Object) -> (same problem of this Question). my answer is Just workaround to Stringify File ObjectSwitch
Stringfying and Serializing are synonymsMoonlight
@williamle8300 yes i known, my answer to solve the case of this question.Switch
@InsanelyADHD as I had comment on previous comment about serializing topic before [Here => #24139716, on comment I mention about my solution was not for serializing File Object But convert File Object to String Only like the question needs(The Same Problem I had face too) !!! Thanks for down vote.Switch
C
11

You have to read the file content using the FileReader API. The File object does not contain the file content (it is just a pointer toward the file, which allows you to read it later).

You can check out this HTML5Rocks article to find out more about the usage of this API.

var file = getAFile( );

var success = function ( content ) {
  console.log( JSON.stringify( content ) ); }

var fileReader = new FileReader( );
fileReader.onload = function ( evt ) { success( evt.target.result ) };
fileReader.readAsText( file );
Choler answered 10/6, 2014 at 10:57 Comment(5)
Thank you for your answer. I want to send the pointer to another server. So I have to convert the file-pointer to a string. Do you have an idea?Malapropism
Did you read the article ? evt.target.result is a string containing the file content. Using the FileReader API is the only way to fetch it, for security reasons.Twoup
I think this is not the solution in my project. There is a problem because I will send the string with GET. The size of the string is too long if the file is for example 500 MB.Malapropism
Well, then don't send it using GET? I'm not sure to understand what you want. If you just need to post a file, do it with FormData rather than JSON, since the former can streamline a file upload without requiring to buffer its content in the RAM.Twoup
You cannot send files via GET. POST is the way here, I don't understand why you would prefer using GET. A web server will never be willing to parse a 500Mo URL.Twoup
G
4

In case anyone is still looking for a solution to this please see my answer on a different post and working example on JSFiddle.

JS:

function getFiles(){
    var files = document.getElementById("myFiles").files;
    var myArray = [];
    var file = {};

    console.log(files); // see the FileList

    // manually create a new file obj for each File in the FileList
    for(var i = 0; i < files.length; i++){

      file = {
          'lastMod'    : files[i].lastModified,
          'lastModDate': files[i].lastModifiedDate,
          'name'       : files[i].name,
          'size'       : files[i].size,
          'type'       : files[i].type,
      } 

      //add the file obj to your array
      myArray.push(file)
    }

    //stringify array
    console.log(JSON.stringify(myArray));
}

HTML:

<input id="myFiles" type="file" multiple onchange="getFiles()" />
Geographical answered 9/2, 2017 at 0:20 Comment(1)
How am i supposed to get the file from this file object in backend?Barnet
S
4

You just need a custom replacer:

function stringify(obj) {
    const replacer = [];
    for (const key in obj) {
        replacer.push(key);
    }
    return JSON.stringify(obj, replacer);
}

const json = stringify(file);
console.log(file);
console.log(json);

Now you should see:

File {name: "xyz.jpg", type: "image/jpeg", size...}
'{"name":"xyz.jpg","type":"image/jpeg","size"...}'
Serranid answered 15/5, 2021 at 0:4 Comment(0)
A
1

Instead of looping through, or rather extracting each key one after the other, i came up with this function and i've used it image input.

const fileObject = e.target.files[0];

important notice

//dont use shorthand for of loop
for (const [key, value] in Object.entries(x)) 
it can't loop through a file object in JS 

Use this code instead

const imageObject = {};

for (const key in fileObject) {
    const value = fileObject[key];
    const notFunction = typeof value !== "function";
    notFunction && (imageObject[key] = value);
}

console.log(imageObject) // => should give you a normal JS object now
Aladdin answered 10/11, 2020 at 19:37 Comment(0)
P
0

You can convert the file to a base64 string and then you can serialize it to json. Was stuck on this problem and took the following approach:

The function to convert to string:

function fileToBase64(file) {
  return new Promise((resolve, reject) => {
    const reader = new FileReader();
    reader.onload = () => resolve(reader.result.split(",")[1]); // Extracting the Base64 string from the data URL
    reader.onerror = reject;
    reader.readAsDataURL(file);
  });
}
Patmore answered 8/3 at 7:1 Comment(0)
C
-1

When you pass a json string Javascript internally trnsform it to Json object and hence no need to parse it.

follow steps in case of of json file ->

$('#inp_import_template')[0].files[0]

Now your json file is transformed to json object (Javascript).

Clemmieclemmons answered 22/11, 2019 at 10:2 Comment(1)
How does this answer the question?Prolongate
S
-3
var obj = {
  name: 'dashu3f'
};

var stringObj = JSON.stringify(obj);
console.log(typeof stringObj);
console.log(stringObj);

open terminal this Folder file and run node json.js

Synchrocyclotron answered 13/7, 2018 at 17:55 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.