post 个文件通过 ajax 个表单数据

post files throught ajax formdata

我使用下面的方法 post 文件通过 ajax,照常工作。

是否可以(允许)像方法 b 那样将文件数据放入对象中?
尝试找到一种组织请求数据的方法。

一个

// 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 ]

更新

感谢@guest271314 和@user4344980 的回答,现在我使用 FileReader 似乎可以,但现在我还有一些问题,

里面 appendFormData() 我评论了 var request = JSON.stringify(request);
一旦我取消注释,那么 request 对象将变为 undefined

我测试过去掉appendRequestDataWithImage()就可以了
问题似乎与 reader.onload 有关 我不知道出了什么问题?我想念什么吗?

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);
    });
  });
}

构建对象

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

    fulfill(request);
  });
}

然后对象添加文件

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);
  });
}

然后对象附加到 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);
  });
}

没有。 $('input')[0].files 不会告诉您它是哪个文件或其内容。 javascript 不允许访问本地文件。

感谢 HTML5,现在可以了。您可以使用文件 API 从文件输入中读取用户选择的文件。然后,将其编码为 Base64,以便将其嵌入 JSON.

读取文件并将其编码为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);
    }
};

ajax post 包含 json 对象的文件使请求数据类似于

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

基于@guest271314 和@user4344980 的回复

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);
    });
  });
}

构建对象

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

    fulfill(request);
  });
}

然后对象添加文件使用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);
  });
}

然后对象追加到 FormData

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

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

    fulfill(formData);
  });
}