Nodejs は、ブラウザからバックエンド サーバーにファイルをアップロードするための Web サーバーとして使用されることがあります。このプロセスでは、Node Web サーバーはデータを適切に処理する必要があります。バックエンドにポストするには、ノード層でファイルのアップロードをシミュレートする必要があります。この記事では主に、マルチパート フォームを実装するためのノード レイヤー シミュレーションのファイル アップロードの例を紹介します。これは非常に参考になるので、皆様のお役に立てれば幸いです。編集者をフォローして見てみましょう。皆さんのお役に立てれば幸いです。
まず、ブラウザ経由でファイルをアップロードします。PostData 形式は次のようになります:
スクリーンショット 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 である可能性があります。現時点では、バッファを String に直接変換することはできず、zlib でデコードしてから String に変換する必要があります。一般的な考え方:
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); } });
それを渡すときに必要になるだけです。 ~~~
関連する推奨事項: フォームアップロード画像の form タグ内の
enctype ="multipart/form-data" の役割
php HTTP リクエスト クラス、GET、POST、Multipart/form をサポート-data
ファイルをアップロードするためのフォームで enctype="multipart/form-data" を設定する必要があるのはなぜですか
以上がマルチパートフォームファイルのアップロードを実現するためのノード層シミュレーションの詳細説明の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。