Node.js はファイルのアップロードを実装します

高洛峰
リリース: 2016-12-24 17:23:20
オリジナル
1524 人が閲覧しました

私は仕事でそのような要求に遭遇しました。以前は、nodejs を使用してファイルをアップロードする方法しか知りませんでした。ブラウザの動作をシミュレートすることと同じです。 Google で検索したところ、ブラウザは http プロトコルを使用してデータをサーバーに送信しているだけであることがわかりました。具体的なプロトコルは、「RFC 1867 - Form-b​​ased File Upload in HTML」です。これは、フォーム フォームを通じてファイルをアップロードする方法です。ブラウザー プロトコルを使用すると、まずブラウザーがサーバーに送信するデータを確認でき、次に同じ方法でアップロード機能を実装できます。ファイルをアップロードするフォームについて言えば、誰もがそれに精通しているはずです:

<form action="http://www.qq.com/" method="post">
<input type="text" name="text1" /><br />
<input type="text" name="text2" /><br />
<input type="submit" />
</form>
ログイン後にコピー


送信時に、フィドラーを使用してパケットをキャプチャすると、そのようなデータがサーバーに送信されることがわかります:

POST http:/ /www.qq .com/ HTTP/1.1
ホスト: www.qq.com
Content-Length: 23
Content-Type: application/x-www-form-urlencoded charset=UTF-8

text1=hello&text2=世界

価値があります。Content-Type のデフォルトは application/x-www-form-urlencoded であるため、メッセージは URL エンコードされることに注意してください。たとえば、「He​​llo」は %E4%BD%A0%E5%A5%BD としてエンコードされます。

次に、フォームからアップロードする方法を見てみましょう。誰もがこれに精通しているはずです:


次に、「hello world」という単語だけを含む新しい Upload.txt テキスト ファイルを作成し、それをアップロードします。次に、fiddler を使用してパッケージをキャプチャします。送信されるデータはもう少し複雑です (キャッシュ制御や Cookie など、他の多くの無関係なリクエスト行は削除されています):


POST http://www.qq.com/ HTTP/1.1

Host: www. qq.com

Content-Length: 199
Content-Type: multipart/form-data; border=----WebKitFormBoundarywr3X7sXBYQQ4ZF5G

------WebKitFormBoundarywr3X7sXBYQQ4ZF5G

Content-Disposition: form-data; ; filename="upload.txt"

Content-Type: text/plain

hello world

-----WebKitFormBoundarywr3X7sXBYQQ4ZF5G--

RFC 1867 の定義に従って、境界データを生成する必要がありますこのデータは、コンテンツ内の他の場所に表示することはできません。これは、各ブラウザの生成アルゴリズムによって異なる場合があります。分離されたデータは、分離されたデータに配置されます。ヘッダーの Content-Type を指定してサーバーに送信します。これは、上記の Content-Type: multipart/form-data; border=----WebKitFormBoundarywr3X7sXBYQQ4ZF5G です。また、アップロードされたコンテンツは、区切り記号を使用して複数のセグメントに分割する必要があります。データの各セグメントにはファイルが含まれており、サーバーはこの名前を使用してファイルを受信します。この例では、ファイルの種類は text/plain です。 png画像はimage/pngです。ファイルタイプの後の空行は、アップロードされたファイルの内容です。この例では、理解しやすいようにテキストファイルがアップロードされているため、画像ファイルがアップロードされている場合は、その内容を直接表示できます。バイナリファイルです、fiddler 文字化けが表示されるだけです。 ファイルの内容が終了した後、空行と境界データが存在します。


送信フォーマットの詳細を理解したら、次はnodejsを使ってプログラミングをしていきます。簡単に言うと、フォーマットに従ってデータをサーバーに送信するだけです。

<form action="http://www.qq.com" method="post" enctype="multipart/form-data">
<input type="file" name="myfile" />
<input type="submit" value="submit" />
</form>
ログイン後にコピー


この記事の焦点は、プロトコルを理解し、それをコードで実装することです。コード構成には最適化のための領域が数多くあります。


最後に、ローカルの Apache で、アップロードしたファイルをテスト用に保存するための php を書きます:

const http = require(&#39;http&#39;);
const fs = require(&#39;fs&#39;);
//post地址为本地服务的一个php,用于测试上传是否成功
var options = {
hostname: &#39;localhost&#39;,
port: 80,
path: &#39;/get.php&#39;,
method: &#39;POST&#39;
}
//生成分隔数据
var boundaryKey = &#39;----WebKitFormBoundaryjLVkbqXtIi0YGpaB&#39;;
//读取需要上传的文件内容
fs.readFile(&#39;./upload.txt&#39;, function (err, data) {
//拼装分隔数据段
var payload = &#39;--&#39; + boundaryKey + &#39;\r\n&#39; + &#39;Content-Disposition:form-data; name="myfile"; filename="upload.txt"\r\n&#39; + &#39;Content-Type:text/plain\r\n\r\n&#39;;
payload += data;
payload += &#39;\r\n--&#39; + boundaryKey + &#39;--&#39;;
//发送请求
var req = http.request(options, function (res) {
res.setEncoding(&#39;utf8&#39;);
res.on(&#39;data&#39;, function (chunk) {
console.log(&#39;body:&#39; + chunk);
});
});
req.on(&#39;error&#39;, function(e) {
console.error("error:"+e);
});
//把boundary、要发送的数据大小以及数据本身写进请求
req.setHeader(&#39;Content-Type&#39;, &#39;multipart/form-data; boundary=&#39;+boundaryKey+&#39;&#39;);
req.setHeader(&#39;Content-Length&#39;, Buffer.byteLength(payload, &#39;utf8&#39;));
req.write(payload);
req.end();
});
ログイン後にコピー


さらに、RFC 1867 によれば、一度に複数のファイルをアップロードする機能も使用できます。詳細については説明しませんが、必要に応じて RFC 1867 を参照してください。


上記は編集者によって紹介されたファイルアップロードの Node.js 実装です。ご質問があればメッセージを残してください。編集者がすぐに返信します。また、PHP 中国語 Web サイトをサポートしていただきありがとうございます。


ファイルアップロードの Node.js 実装に関連するその他の記事については、PHP 中国語 Web サイトに注目してください。

関連ラベル:
ソース:php.cn
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
最新の問題
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート
私たちについて 免責事項 Sitemap
PHP中国語ウェブサイト:福祉オンライン PHP トレーニング,PHP 学習者の迅速な成長を支援します!