0

I use below method a post files through ajax, work as usual.

is it possible (allow) to put the files data inside object like method b?
try to find a way organise the request data.

a

// client side
var formData = new FormData();    
var fileLength = $('input')[0].files.length;
for (var i = 0; i < fileLength; i++) {
  formData.append("files[]", $('input')[0].files[i]);
}


// server side  nodejs
var file = req.files.file;
// .. use file  move file location or do other things
// { file: 
//  [ { fieldName: 'file[]',
//      originalFilename: '....png',
//      path:'....png',
//      headers: [Object],
//      size: 10854,
//      name: '....png',
//      type: 'image/png' } ] }

b

// client side   
var formData = new FormData();
var request = {};
request.image = {};
// request.image.description = 'str';
// ...

request.image.files = {};
request.image.files = $('input')[0].files;

var request = JSON.stringify(request);    
formData.append("request", request);

// server side  nodejs
// not working
// cant find the file 
// output request.image.files only get list: [ { '0': {}, length: 1 }, [length]: 1 ]

UPDATE

thanks for @guest271314 and @user4344980 answer, now I use FileReader seems will be work, but now I still have some problem ,

inside appendFormData() I commented var request = JSON.stringify(request);
once I uncomment then request object will become undefined.

I did test if I remove appendRequestDataWithImage() will be ok.
seems the problem related to reader.onload I don't know whats wrong? do I miss something?

function onclickSubmit() {
    $('.submit').on('click', '.button', function() {
      appendFormDataSubmit();
      // self.global().requestPost(url, appendFormDataSubmit()).then(function(response) {

      // });
    });
  }

function appendFormDataSubmit() {
  return new Promise(function (fulfill, reject){
    appendRequestDataWithoutImage().then(function(result) {
      return appendRequestDataWithImage(result);
    }).then(function(result) {
      console.log(result);
      return appendFormData(result);
    }).then(function(result) {
      console.log(result);
      fulfill(result);
    });
  });
}

build object

function appendRequestDataWithoutImage() {
  return new Promise(function (fulfill, reject){
    var request = {};
    request.data = {};
    request.data.text = 'text';

    fulfill(request);
  });
}

then object add files

function appendRequestDataWithImage(request) {
  return new Promise(function (fulfill, reject){
    var files = self.el.data.find('.dataContainer .data.userInformation.image .content input')[0].files;
    // console.log(files);
    var file = files[0];

    var reader = new FileReader();

    reader.onload = function(readerEvt) {

      var binaryString = readerEvt.target.result;
    //   // request.data[file.name] = btoa(binaryString);
      request.data.images = btoa(binaryString);

      fulfill(request);
      console.log('load done');
    }

    reader.readAsBinaryString(file);
  });
}

then object append to FormData

function appendFormData(request) {
  return new Promise(function (fulfill, reject){
    console.log(request);
    // var request = JSON.stringify(request);
    // console.log(request);

    var formData = new FormData();
    formData.append("request", request);

    fulfill(formData);
  });
}
user1575921
  • 1,078
  • 1
  • 16
  • 29
  • Seems like an unnecessary step to take. Any specific reason why other that organization? Your object ends up as a property of formData anyway, right? – Aaron Wagner Mar 18 '16 at 02:13
  • What is purpose of attempting to convert `File` object to `Object` ? You can assign `File` object as value of a `request.image.files` property, though why where `FormData` returns expected results at server-side ? – guest271314 Mar 18 '16 at 02:13
  • @AaronWagner thanks for reply just try to sort them well, because there is a lot different groups include images and text. – user1575921 Mar 18 '16 at 02:20
  • @guest271314 thanks for reply. I can't understand `assign File object as value of a request.image.files property` can you show me some example code ? – user1575921 Mar 18 '16 at 02:23
  • What are you trying to achieve ? – guest271314 Mar 18 '16 at 02:28
  • @guest271314 send request data looks like {[ image1: { description: text, file: file }, iimage2: { description: text, file: file }] } – user1575921 Mar 18 '16 at 02:30
  • See http://stackoverflow.com/questions/28856729/upload-multiple-image-using-ajax-php-and-jquery/29109577?s=1|0.3891#29109577 – guest271314 Mar 18 '16 at 02:33
  • @guest271314 is that mean I can use somethin like `var reader = new FileReader(); reader.readAsDataURL(new Blob([file], { "type": file.type }));` to get file information like method a server side ? – user1575921 Mar 18 '16 at 02:42
  • Yes, have you reviewed `js` at link ? – guest271314 Mar 18 '16 at 02:44
  • @guest271314 please see my update code in question. I can't find way correct do `promise` with `FileReader` and stuck in callback can't return formdata to submit . – user1575921 Mar 18 '16 at 04:56
  • @user1575921 What is returned from `self.global()` ? Not entirely certain of logic ? Are you posting request before `formData` is defined ? What is purpose of `appendfiles` ? What is `request` and `file` at `self.global().appendfiles(request, file)` ? – guest271314 Mar 18 '16 at 05:09
  • 1
    @guest271314 I fix this !!! thanks so much for your help – user1575921 Mar 18 '16 at 06:09
  • 1
    @user1575921 You could post and accept your own solution http://stackoverflow.com/help/self-answer – guest271314 Mar 18 '16 at 06:15

3 Answers3

1

Thanks for HTML5, it possible now. You can use file API to read users selected file from file input. Then, encode it to Base64 to allow you embed it into JSON.

Example of reading and encoding file to Base64: http://jsfiddle.net/eliseosoto/JHQnk/

var handleFileSelect = function(evt) {
    var files = evt.target.files;
    var file = files[0];

    if (files && file) {
        var reader = new FileReader();

        reader.onload = function(readerEvt) {
            var binaryString = readerEvt.target.result;
            request.image.files[file.name] = btoa(binaryString);
        };

        reader.readAsBinaryString(file);
    }
};
user4344980
  • 383
  • 1
  • 3
  • 6
1

ajax post file with json object make request data like

{
  "data": {
    "text": "text",
    "images": binaryString
  }
}

base on @guest271314 and @user4344980 response

function onclickSubmit() {
    $('.submit').on('click', '.button', function() {
      appendFormDataSubmit();
      // requestPost with appendFormDataSubmit() return
    });
  }

function appendFormDataSubmit() {
  return new Promise(function (fulfill, reject){
    appendRequestDataWithoutImage().then(function(result) {
      return appendRequestDataWithImage(result);
    }).then(function(result) {
      return appendFormData(result);
    }).then(function(result) {
      fulfill(result);
    });
  });
}

build object

function appendRequestDataWithoutImage() {
  return new Promise(function (fulfill, reject){
    var request = {};
    request.data = {};
    request.data.text = 'text';

    fulfill(request);
  });
}

then object add files use FileReader

function appendRequestDataWithImage(request) {
  return new Promise(function (fulfill, reject){
    var files = self.el.data.find('.dataContainer .data.userInformation.image .content input')[0].files;
    var file = files[0];

    var reader = new FileReader();

    reader.onload = function(readerEvt) {
      var binaryString = readerEvt.target.result;
      request.data.images = btoa(binaryString);

      fulfill(request);
    }

    reader.readAsBinaryString(file);
  });
}

then object append to FormData

function appendFormData(request) {
  return new Promise(function (fulfill, reject){
    request = JSON.stringify(request);

    var formData = new FormData();
    formData.append("request", request);

    fulfill(formData);
  });
}
user1575921
  • 1,078
  • 1
  • 16
  • 29
0

No. $('input')[0].files doesn't give you which file it is or its contents. It is not allowed for javascript to access local files.

v7d8dpo4
  • 1,399
  • 8
  • 9