Heim  >  Artikel  >  Web-Frontend  >  Ausführliche Erläuterung der Knotenschichtsimulation zur Implementierung des mehrteiligen Formulardatei-Uploads

Ausführliche Erläuterung der Knotenschichtsimulation zur Implementierung des mehrteiligen Formulardatei-Uploads

小云云
小云云Original
2018-01-03 09:29:431847Durchsuche

Manchmal besteht eine solche Anforderung, dass Nodejs als Webserver zum Hochladen von Dateien vom Browser auf den Back-End-Server verwendet wird Daten entsprechend, dann im Backend posten, dann müssen Sie den Datei-Upload auf der Knotenebene simulieren. In diesem Artikel wird hauptsächlich ein Datei-Upload-Beispiel für die Node-Layer-Simulation zur Implementierung eines mehrteiligen Formulars vorgestellt. Es hat einen guten Referenzwert und ich hoffe, dass es für alle hilfreich sein wird. Folgen wir dem Herausgeber und schauen wir uns das an. Ich hoffe, es kann allen helfen.

Laden Sie zunächst die Datei über den Browser hoch. Das PostData-Format sieht so aus:

Screenshot 22.11.2014 21.18.45 Uhr

Wie in der Abbildung gezeigt, wird jeder Datensatz tatsächlich durch „-----WebkitFormBoundary....“ getrennt und endet schließlich mit diesem Trennzeichen. Dieses Trennzeichen ist vollständig anpassbar.

Jedes übermittelte Datenelement wird durch Content-Disposition beschrieben. Wenn Content-Type nicht angegeben ist, ist der Standardwert text/plain. Wenn es sich um eine hochgeladene Binärdatei handelt, geben Sie einfach deren Mime-Typ an.

Kapseln Sie einfach eine Methode zum Implementieren des Datei-Uploads auf der Knotenebene:

/**
 * 上传文件
 * @param files  经过formidable处理过的文件
 * @param req  httpRequest对象
 * @param postData 额外提交的数据
 */
function uploadFile(files, req, postData) {
 var boundaryKey = Math.random().toString(16);
 var endData = '\r\n----' + boundaryKey + '--';
 var filesLength = 0, content;

 // 初始数据,把post过来的数据都携带上去
 content = (function (obj) {
  var rslt = [];
  Object.keys(obj).forEach(function (key) {
   arr = ['\r\n----' + boundaryKey + '\r\n'];
   arr.push('Content-Disposition: form-data; name="' + key + '"\r\n\r\n');
   arr.push(obj[key]);
   rslt.push(arr.join(''));
  });
  return rslt.join('');
 })(postData);

 // 组装数据
 Object.keys(files).forEach(function (key) {
  if (!files.hasOwnProperty(key)) {
   delete files.key;
   return;
  }
  content += '\r\n----' + boundaryKey + '\r\n' +
   'Content-Type: application/octet-stream\r\n' +
   'Content-Disposition: form-data; name="' + key + '"; ' +
   'filename="' + files[key].name + '"; \r\n' +
   'Content-Transfer-Encoding: binary\r\n\r\n';
  files[key].contentBinary = new Buffer(content, 'utf-8');
  filesLength += files[key].contentBinary.length + fs.statSync(files[key].path).size;
 });

 req.setHeader('Content-Type', 'multipart/form-data; boundary=--' + boundaryKey);
 req.setHeader('Content-Length', filesLength + Buffer.byteLength(endData));

 // 执行上传
 var allFiles = Object.keys(files);
 var fileNum = allFiles.length;
 var uploadedCount = 0;
 allFiles.forEach(function (key) {
  req.write(files[key].contentBinary);
  var fileStream = fs.createReadStream(files[key].path, {bufferSize: 4 * 1024});
  fileStream.on('end', function () {
   // 上传成功一个文件之后,把临时文件删了
   fs.unlink(files[key].path);
   uploadedCount++;
   if (uploadedCount == fileNum) {
    // 如果已经是最后一个文件,那就正常结束
    req.end(endData);
   }
  });
  fileStream.pipe(req, {end: false});
 });
}

Das ist die Idee, und der Code ist nicht kompliziert. Worauf Sie möglicherweise besonders achten müssen Antwortverarbeitung von http.request, Antwort.header kann derzeit nicht direkt in String konvertiert werden. Er muss von zlib dekodiert und dann in String konvertiert werden >

Markieren Sie es. Vielleicht brauchen Sie es, wenn Sie vorbeikommen~~~
var result = [];
response.on('data', function (chunk) {
 result.push(chunk);
});

// 处理response
var _dealResponse = function (data) {
 var buffer = data;
 try {
  data = data.toString('utf8');
  data = data ? (JSON.parse(data) || data) : false;
 } catch (err) {
  // 接口返回数据格式异常,解析失败
  console.log(err);
 }

 self.res.writeHead(response.statusCode, 'OK', {
  'content-type': 'text/plain; charset=utf-8',
  'content-length': buffer.length
 });
 self.res.write(buffer);
 self.res.end();
};

response.on('end', function () {
 result = Buffer.concat(result);
 // gzip 的数据,需要zlib解码
 if (response.headers['content-encoding'] == 'gzip') {
  zlib.gunzip(result, function (err, dezipped) {
   var data = err ? new Buffer('{}') : dezipped;
   _dealResponse(data);
  });
 } else {
  _dealResponse(result);
 }
});

Verwandte Empfehlungen:


Die Rolle von enctype="multipart/form-data" im Formular-Tag zum Hochladen von Bildern im Formular

PHP-HTTP-Anfrageklasse, unterstützt GET, POST, Multipart/form-data

Warum Muss das Formular zum Hochladen von Dateien enctype="multipart/form-data"

festlegen?

Das obige ist der detaillierte Inhalt vonAusführliche Erläuterung der Knotenschichtsimulation zur Implementierung des mehrteiligen Formulardatei-Uploads. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn