>  기사  >  웹 프론트엔드  >  노드 레이어를 사용하여 멀티파트 양식 파일 업로드를 구현하는 방법

노드 레이어를 사용하여 멀티파트 양식 파일 업로드를 구현하는 방법

亚连
亚连원래의
2018-06-14 11:48:171472검색

이제 멀티파트 형식을 구현하기 위해 노드 레이어 시뮬레이션을 사용한 파일 업로드의 예를 공유하겠습니다. 이는 좋은 참고 가치가 있으며 모든 사람에게 도움이 되기를 바랍니다.

때때로 그런 요구가 있습니다. Nodejs는 브라우저에서 백엔드 서버로 파일을 업로드하는 데 사용됩니다. 이 프로세스에서 Node 웹 서버는 데이터 전송만 수행합니다. 적절하게 선택한 다음 백엔드에 게시한 다음 노드 계층에서 파일 업로드를 시뮬레이션해야 합니다.

먼저 브라우저를 통해 파일을 업로드합니다. PostData 형식은 다음과 같습니다.

Screenshot 2014-11-22 pm 9.18.45.png

그림과 같이 각 세트는 data 실제로는 "------WebkitFormBoundary...."로 구분되며 최종적으로 이 구분 기호로 끝납니다. 또한 이 구분 기호는 완전히 사용자 정의할 수 있습니다.

제출된 각 데이터는 Content-Disposition으로 설명됩니다. Content-Type이 지정되지 않은 경우 기본값은 text/plain입니다. 업로드된 바이너리 파일인 경우 MIME 유형을 지정하면 됩니다.

노드 계층에서 파일 업로드를 구현하는 방법을 간단히 캡슐화합니다.

/**
 * 上传文件
 * @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});
 });
}

아이디어는 이렇고 코드는 복잡하지 않습니다. 특별히 주의해야 할 점은 응답 처리에 있다는 것입니다. http.request, response.headers는 gzip입니다. 이때 버퍼는 문자열로 직접 변환할 수 없습니다. zlib로 디코딩한 후 문자열로 변환해야 합니다.

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

표시하세요. 그냥 지나갈 때 필요할 수도 있어요~~

위 내용은 모두를 위해 정리한 내용입니다. 앞으로 모든 분들께 도움이 되길 바랍니다.

관련 기사:

HTTP의 Gzip 압축 문제

JS 코드를 사용하여 스네이크 게임을 작성하는 방법(자세한 튜토리얼)

Javascript에서 경로를 base64 인코딩으로 변환하는 방법

위 내용은 노드 레이어를 사용하여 멀티파트 양식 파일 업로드를 구현하는 방법의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.