Node.js 開発チュートリアル: OnceIO フレームワークに基づくファイルのアップロードと検証機能の実装

高洛峰
リリース: 2016-12-03 13:36:01
オリジナル
1135 人が閲覧しました

OnceIO は、OnceDoc エンタープライズ コンテンツ (ネットワーク ディスク) の基盤となる Web フレームワークであり、テンプレート ファイルと静的ファイルの完全なキャッシュを実現でき、実行には I/O 操作がまったく必要なく、クライアント キャッシュの最適化、GZIP 圧縮、など (最初の圧縮のみ) は非常に優れたパフォーマンスを発揮し、サーバーのコストを節約します。そのモジュラー機能により、Web を分散方式で保存できます。つまり、拡張パッケージにはフロントエンド、バックエンド、およびデータベース定義が含まれており、ディレクトリを追加/削除することで関数を削除し、真のモジュラー拡張を実現できます。 OnceIOの使い方を紹介する連載記事です。

この章では、OnceIO を使用してファイル アップロード機能を実装する方法を説明します。

Web ページ ファイルにフォームを構築します

例として、ファイル アップロード機能のみを備えた単純な Web ページ file.html を取り上げます。

<!DOCTYPE html>
<html>
<body>
<form method="post" enctype="multipart/form-data" action="/file/upload">
<input type="file" name="file" /><br>
<input type="submit" value="Upload" />
</form>
</body>
</html>
ログイン後にコピー

ブラウザの表示効果は次のようになります。

Node.js 開発チュートリアル: OnceIO フレームワークに基づくファイルのアップロードと検証機能の実装

空白のバーまたは「参照...」ボタンを使用すると、ファイル参照ウィンドウを開いて、アップロードする必要のあるファイルを選択できます:

Node.js 開発チュートリアル: OnceIO フレームワークに基づくファイルのアップロードと検証機能の実装

サーバー受信ファイルロジックを確立します

サーバーファイルのwebsvr.jsコードは次のようになります:

var fs = require(&#39;fs&#39;)
var path = require(&#39;path&#39;)
var onceio = require(&#39;../onceio/onceio&#39;)
var app = onceio()
app.get(&#39;/&#39;, function(req, res){
res.render(&#39;file.html&#39;)
})
app.file(&#39;/file/upload&#39;, function(req, res) {
var fileInfo = req.files.file || {}
fs.link(fileInfo.path, path.join(&#39;./fileStore&#39;, fileInfo.name))
res.send(&#39;File Uploaded Successfully&#39;)
}).before(function(req, res) {
var contentLength = req.headers[&#39;content-length&#39;] || 0
if (contentLength > 1048576) {
res.send({ error: &#39;Error: File Size Limit (1 MB) Exceeded&#39; })
} else {
return true
}
})
ログイン後にコピー

var fs = require('fs') と var path = require('path') は、それぞれ Node.js が提供するファイル操作用のファイル システム (fs) モジュールとファイル パスを処理するパス モジュールをインポートします。

app.file(path, callback).before(callback) は app.use(path, callback, {file: true}).before(callback) と同等で、アップロードされたファイルを処理するミドルウェアです。

ファイルがアップロードされると、そのサイズ、ストレージアドレス、名前、形式、および変更時刻が req.files の file 属性に配置されます (名前はタイプ「file」の入力タグ内の name の値です)。そのサイズ情報は、req.headers の content-length 属性に配置されます。

before 関数

before は、OnceIO と他の Web フレームワークの主な違いの 1 つです。最高のパフォーマンスを得るために、ファイルを受信する前に、サイズ、タイプなどの基本的な検証を実行できます。 true を返すと、検証が成功してファイルの受信が開始されることを示します。そうでない場合は、接続が閉じられ、アップロードがキャンセルされます。以前は、セッションがファイルまたはデータベース Redis に存在する可能性があり、セッションの取得は時間がかかる非同期プロセスであるため、req.session オブジェクトは使用できませんでした。 before 関数は、ファイルの合法性を即座に判断する必要があります。

この例では、before コールバック関数は、req.headers の content-length に基づいて、アップロードされたファイルがサイズ制限を超えているかどうかを判断します (開発者は、if ステートメントの定数を変更することで、ファイルのアップロード サイズの上限を変更できます。 content-length の単位はバイト、1024 * 1024 は 1 MB を表します)、それを超えた場合、ファイルはアップロードされず、超えていない場合、関数の戻り値は true です。 、サーバーは引き続き app.file のコールバック関数を実行して、一時アドレスからファイルを転送します。アドレスは指定されたストレージアドレスに転送され、ファイルはここにアップロードされます。

ファイル名が重複する問題を解決する

現在のサーバープログラムではファイル名が重複する問題を解決できません。ユーザーが同じ名前のファイルをアップロードすると、サーバーはファイルがすでに存在するというエラーを返します。この問題を解決するには、ファイルのメインファイル名と拡張子名の間にタイムスタンプを追加します。この処理の関数コードは次のとおりです。

var timestampName = function(fileName){
// get filename extension
var extName = path.extname(fileName) 
// get base name of the file
var baseName = path.basename(fileName, extName)
// insert timestamp between base name and filename extension
// the plus sign (&#39;+&#39;) before new Date() converts it into a number
return baseName + +new Date() + extName
}
ログイン後にコピー

次に、fs.link ステートメントの fileInfo.name を次のように置き換えます。 timestampName(fileInfo.name):

fs.link(fileInfo.path, path.join(&#39;./fileStore&#39;, timestampName(fileInfo.name)))
ログイン後にコピー

改良されたサーバー プログラムにより、ユーザーは同じ名前のファイルをアップロードできるようになります。例として、「cache_workflow.png」という名前のファイルを 5 回アップロードすると、サーバーのファイル ストレージ アドレスに 5 つの名前が表示されます。 「cache_workflow」で始まるがタイムスタンプが異なるファイル:


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