国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 編程 > JavaScript > 正文

Node層模擬實現multipart表單的文件上傳示例

2019-11-19 14:36:58
字體:
來源:轉載
供稿:網友

有時候就是有這樣的需求,Nodejs做webserver,從瀏覽器端上傳文件到后端服務器,Node層只是做一個數據中轉,如果在這個過程中,Node webserver需要對數據進行適當加工,然后再Post到后端,那么就得在Node層模擬文件上傳了。

首先,通過瀏覽器上傳文件,PostData格式是長著個樣子的:

屏幕快照 2014-11-22 下午9.18.45.png

如圖,每一組數據其實就是用“-----WebkitFormBoundary.....”分隔開的,最后再用這個分隔符結束,而且,這個分隔符完全是可自定義的。

每一段提交數據,則通過Content-Disposition來描述,未指定Content-Type,則默認text/plain,如果是上傳的二進制文件,指定其mime-type即可。

簡單封裝一個方法,實現Node層的文件上傳:

/** * 上傳文件 * @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處理中,response.headers可能是gzip的,這個時候buffer不能直接toString,需要通過zlib解碼再轉換為string,大概思路:

var result = [];response.on('data', function (chunk) { result.push(chunk);});// 處理responsevar _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); }});

Mark一下,也許你路過正好需要~~~

以上這篇Node層模擬實現multipart表單的文件上傳示例就是小編分享給大家的全部內容了,希望能給大家一個參考,也希望大家多多支持武林網。

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 汶川县| 芦溪县| 武宣县| 怀来县| 抚州市| 衡山县| 保山市| 和林格尔县| 福州市| 望江县| 昂仁县| 佳木斯市| 关岭| 长岛县| 始兴县| 绥中县| 浦县| 桃源县| 临夏县| 安仁县| 岐山县| 当雄县| 从化市| 舒城县| 南充市| 安达市| 普定县| 冀州市| 尚义县| 巴林右旗| 蒙山县| 万年县| 岗巴县| 南溪县| 江阴市| 桐梓县| 盱眙县| 阳朔县| 奎屯市| 平凉市| 江都市|