>  기사  >  웹 프론트엔드  >  멀티파트 양식 파일 업로드를 구현하기 위한 노드 레이어 시뮬레이션에 대한 자세한 설명

멀티파트 양식 파일 업로드를 구현하기 위한 노드 레이어 시뮬레이션에 대한 자세한 설명

小云云
小云云원래의
2018-01-03 09:29:431886검색

때때로 그런 요구가 있습니다. Nodejs는 브라우저에서 백엔드 서버로 파일을 업로드하는 데 사용됩니다. Node 레이어는 이 프로세스 동안 데이터를 적절하게 처리하고 그런 다음 백엔드에 게시하려면 노드 계층에서 파일 업로드를 시뮬레이션해야 합니다. 이 글은 멀티파트 형태를 구현하기 위한 노드 레이어 시뮬레이션의 파일 업로드 예시를 주로 공유합니다. 이는 좋은 참고 가치가 있으며 모든 사람에게 도움이 되기를 바랍니다. 편집자를 따라 살펴보겠습니다. 모두에게 도움이 되기를 바랍니다.

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

Screenshot 2014-11-22 9.18.45.png

그림에 표시된 것처럼 각 데이터 세트는 실제로 " -----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);
 }
});

표시하세요. 어쩌면 지나갈 때 필요할 수도 있습니다. ~~

관련 권장사항:

enctype 양식 업로드 이미지의 form 태그에 있음 ="multipart/form-data"

php HTTP 요청 클래스의 역할, GET, POST, Multipart/form 지원 -data

파일 업로드 양식에 enctype="multipart/form-data"

를 설정해야 하는 이유는 무엇인가요?

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

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