【问题标题】:post files throught ajax formdata通过ajax formdata发布文件
【发布时间】:2016-03-18 02:06:08
【问题描述】:

我使用下面的方法通过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);
  });
}

【问题讨论】:

  • 似乎是一个不必要的步骤。其他该组织的任何具体原因?你的对象最终还是作为 formData 的一个属性,对吧?
  • 尝试将 File 对象转换为 Object 的目的是什么?您可以将File 对象分配为request.image.files 属性的值,但为什么FormData 在服务器端返回预期结果?
  • @AaronWagner 感谢您的回复,请尝试对它们进行分类,因为有很多不同的组,包括图像和文本。
  • @guest271314 我解决了这个问题!!!非常感谢您的帮助
  • @user1575921 您可以发布并接受您自己的解决方案stackoverflow.com/help/self-answer

标签: javascript ajax node.js post multipartform-data


【解决方案1】:

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

【讨论】:

    【解决方案2】:

    带有json对象的ajax发布文件请求数据,如

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

    【讨论】:

      【解决方案3】:

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

      【讨论】:

      • 感谢您的回复。为什么方法a可以工作?如果无法访问文件,它会发布什么内容??
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-08-04
      • 2018-05-20
      • 1970-01-01
      • 2015-07-08
      • 2017-05-14
      • 1970-01-01
      相关资源
      最近更新 更多