如何从JS上传预览文件到PHP

时间:2015-02-16 20:43:03

标签: javascript php html

我正在开展一个项目,我试图允许用户通过将xlsx文件拖放到框中来上传xlsx文件(而不是预览版)进行处理。我想让它像smallpdf's那样工作。我已经能够使用this group of files从用户那里获取文件名以及我认为的二进制字符串:

if(window.FileReader) { 
 var drop; 
 addEventHandler(window, 'load', function() {
    var status = document.getElementById('status');
    drop   = document.getElementById('drop');
    var list   = document.getElementById('list');

    function cancel(e) {
      if (e.preventDefault) { e.preventDefault(); }
      return false;
    }

    // Tells the browser that we *can* drop on this target
    addEventHandler(drop, 'dragover', cancel);
    addEventHandler(drop, 'dragenter', cancel);

addEventHandler(drop, 'drop', function (e) {
  e = e || window.event; // get window.event if e argument missing (in IE)   
  if (e.preventDefault) { e.preventDefault(); } // stops the browser from redirecting off to the image.

  var dt    = e.dataTransfer;
  var files = dt.files;
  for (var i=0; i<files.length; i++) {
    var file = files[i];
    var reader = new FileReader();

    //attach event handlers here...

    reader.readAsDataURL(file);
addEventHandler(reader, 'loadend', function(e, file) {
    var bin           = this.result; 
    var newFile       = document.createElement('div');
    newFile.innerHTML = 'Loaded : '+file.name+' size '+file.size+' B';
    list.appendChild(newFile);  
    var fileNumber = list.getElementsByTagName('div').length;
    status.innerHTML = fileNumber < files.length 
                     ? 'Loaded 100% of file '+fileNumber+' of '+files.length+'...' 
                     : 'Done loading. processed '+fileNumber+' files.';

    var img = document.createElement("img"); 
    img.file = file;   
    img.src = bin;
    list.appendChild(img);
}.bindToEventHandler(file));
  }
  return false;
});
Function.prototype.bindToEventHandler = function bindToEventHandler() {
  var handler = this;
  var boundParameters = Array.prototype.slice.call(arguments);
  //create closure
  return function(e) {
      e = e || window.event; // get window.event if e argument missing (in IE)   
      boundParameters.unshift(e);
      handler.apply(this, boundParameters);
  }
};
  });
} else { 
  document.getElementById('status').innerHTML = 'Your browser does not support the HTML5 FileReader.';
}
function addEventHandler(obj, evt, handler) {
    if(obj.addEventListener) {
        // W3C method
        obj.addEventListener(evt, handler, false);
    } else if(obj.attachEvent) {
        // IE method.
        obj.attachEvent('on'+evt, handler);
    } else {
        // Old school method.
        obj['on'+evt] = handler;
    }
}

此外,我的网页正文中的HTML也会编写如下。

<div id="file-container">
  <div id="status">Drag the files from a folder to the selection area below ...</div>
  <div id="drop">Drop Spreadsheet here</div>
  <div id="list"></div>
</div><!--eod #file-container-->

如你所见,我实际上并没有使用表格。我是否必须使用表单将文件发送到PHP?如果是,还有其他选择吗?

我不确定如何将文件从我的JavaScript代码传输到我的实际PHP来处理文件。任何帮助,将不胜感激。我做了大量研究,但没有成功。如果你认为另一种做法会更好,我可以接受建议。

2 个答案:

答案 0 :(得分:2)

我是smallpdf的开发者。我们直接在请求正文中上传文件,没有multipart / form-data。也无需使用FileReader API。 XMLHttpRequests send方法接受File / Blob等作为参数。

我们上传的简化版本如下:

function upload(file) {
  var req = new XMLHttpRequest();

  req.addEventListener('load', function () {
    console.log(req.statusCode, req.responseText);
  }.bind(this));


  req.upload.addEventListener('progress', function (ev) {
    console.log('progress', ev.loaded / file.size * 100);
  }.bind(this));

  req.upload.addEventListener('error', errorHandler);
  req.addEventListener('error', errorHandler);

  req.open('POST', '/upload/url', true);
  req.setRequestHeader('Content-Type', file.type);

  // Posts the file in the request body
  req.send(file);
}

function errorHandler(error)  {
  console.log(error)
}

你可以使用这样的东西来获取droped文件或使用输入字段的文件。

var dropElement = document.body;

function cancel(ev) {
  ev.preventDefault();
}
// cancel dragover event
dropElement.addEventListener('dragover', cancel);

// listen for drop events
dropElement.addEventListener('drop', function (ev) {
  cancel(ev);
  var files = [].slice.call(ev.dataTransfer.files);
  files.forEach(upload);
});

答案 1 :(得分:0)

阅读完文件后尝试执行以下操作:

  var fileContents = new FormData();
  fileContents.append('file', bin);
  $.ajax({
    url :  "processFile.php",
    type: 'POST',
    data: fileContents,
    contentType: false,
    processData: false,
    success: function(data) {
      alert("File sent sucessfully");
    },    
    error: function() {
      alert("Something went wrong");
    }
  });