webファイルのアップロード

16974 ワード

一、導入する
webアプリケーションの発展に伴って、webアプリケーションがますます豊富になり、ファイル操作がソフトウェアの必要性になりました.ブラウザを使って様々な形式のファイルをアップロードし、nodejsでアップロードされたファイルを処理しますか?ファイルのアップロードについて分析します.
二、選択ファイル
まずファイルをアップロードしたいなら、最低でもブラウザに知らせてください.アップロードされたファイルはどれですか?
二つの選択ファイルの方式
1.inputファイル選択
ブラウザのinputタブでtype属性がfileの場合、このタブをクリックすると、ブラウザがシステムのファイル選択器を開き、ファイル選択ができます.
<input type="file" id="file" multiple="multiple">
file = document.getElementById('file');
file.onclick = function(e){
    e.target.value=""
}
file.onchange = function(e){
	console.log(e.target.files)
    console.log(e.target.value)
}
  • は、一般的にinputタグを設定したchangeイベントによってファイルの変化を監視し、inputが選択したファイルが変化すると、このイベントを再起動する.
  • は、イベントコールバックにおいて、e.targetにトリガの要素、すなわちinputラベルを記録している.ラベルのvalue属性は、選択されたファイルの具体的な位置、ラベルのfiles属相がファイルの名称・サイズ・タイプなどの情報を記録しています.
  • 一般的にファイルを使用して選択する場合、デフォルトでは一つのファイルしか選択できません.複数のファイルに触れると、inputのhtmlにmultiple=「multiple」を追加することができます.複数のファイルを選択できるように選択します.
  • において、複数のファイルを選択する際に、files配列に格納されたコンテンツは、複数のファイルの配列であることに留意されたい.ただし、value属性は文字規則に従って並べ替えられた最初のファイルのみに制限されます.
  • ファイル選択時には同じパスのファイルしか選択できません.フォルダをまたいでファイルを選択することはできません.
  • にはまだいくつかの問題があります.同じファイルを2回選択すると、ファイルが変更されていないため、changeイベントはまったくトリガされません.キャンセルボタンをクリックするか、value値が空になりました.イベントが異常にトリガされました.
  • この時、私たちはイベントをクリックし、ファイルがクリックした時にそのvalue属性をクリアすることができます.
  • 以降、ファイル選択器を開くと、どのファイルを選択する前に選択されていてもイベントが発生します.
  • 以降はキャンセルボタンをクリックします.valueは以前から空きましたので、changeの更新をトリガしません.
  • 2.jsファイルのドラッグ選択
    新版w 3 c仕様では、ブラウザは元のドラッグイベントをサポートしています.このようにファイルを選択するためにドラッグ機能を使うことができます.
    ドラッグ機能を使うには、まず、どのようなドラッグ事件があるかを確認します.
  • ドラッグされた要素は、ドロップトリガ
  • を開始します.
  • ドラッグされたオブジェクト:ドラゴイベント、ドラッグ&ドロップされた要素、ドラッグ&ドロップ中
  • 被牽引対象:dragentイベント、ドラッグ&ドロップの対象要素、ドラッグ&ドロップ操作終了
  • 通過対象:dragenterイベント、ドラッグ&ドロップ中にマウスが通過する要素、ドラッグ&ドロップされた要素「開始」は他の要素の範囲に入る(エントリしたばかり)
  • .
  • 通過対象:dragoverイベント、ドラッグ&ドロップ中にマウスが通過する要素は、ドラッグ&ドロップされた要素がこの要素の範囲内で移動しています.
  • 通過対象:dragleaveイベント、ドラッグ&ドロップ中にマウスが通過した要素は、ドラッグ&ドロップされた要素がこの要素の範囲から離れます.
  • ターゲット地点:dropイベント、ドラッグ&ドロップのターゲット要素、その他の要素はこの要素にドラッグ&ドロップされます.
    var oBox = document.getElementById('box');
    //       
    oBox.ondragenter = function() {
        oBox.innerHTML = '     ';
    };
    oBox.ondragleave = function() {
        oBox.innerHTML = '          ';
    };
    oBox.ondrop = function(ev) {
        console.log(ev.dataTransfer.files);
    };
    
  • は、ondropイベントがトリガされると、ev.dataTransfer.filesに選択されたファイルが含まれていますが、イベントコールバックパラメータは参照タイプであるため、コールバック関数においてのみ関連するファイル情報が取得でき、その後に参照先によってアクセスされたファイルリストは空になります.
  • ファイルを指定の場所にドラッグしないと、ブラウザのデフォルトイベントがトリガされ、ブラウザが新しいページを開いて、ファイルをアップロードするのではなくプログラムを直接実行することになる.この時には、同時にdocumentにondragover、ondropイベントを追加し、彼らのデフォルトイベントを禁止する必要があります.このようにして、ブラウザは新しいページを開けないようにします.
  • 三、ファイルアップロード
    前のファイル選択を経て、アップロードの目標を確定したら、ファイルの具体的なアップロードができます.
    書類提出
    ajaxファイルのアップロードにはFormDataというブラウザの元のオブジェクトが必要です.オブジェクトのプロトタイプ方法apendを通じて、ファイルの内容をアナログフォームに変換します.その後、ajaxのpostメソッドでバックグラウンドに提出します.
    var form = new FormData()
    form.append('files', oFile);//   oFile                 
    console.log(form)//             
    
    url = 'http://localhost:1949/upload', //       
    var xhr = new XMLHttpRequest();
    xhr.open("post", url, true);
    xhr.send(form); //    
    
    注意:生成されたフォームの例では、コンソールの印刷ではファイルが追加されているとは見えません.空のオブジェクトのように見えます.これは結合されたファイルがバイナリで書かれているため、コンソールではデータ解析ができません.
    postトラッキング分析
    ここで注意したいのは、post要求を使用して送信する前に、最初に一度のoptions接続が行われ、接続が確立されてもよいと判断された場合に、本当のpost要求が開始されることである.以下はFiddlerがつかむローカルテストのpostパケットです.
    POST http://localhost:1949/upload HTTP/1.1
    Host: localhost:1949
    Connection: keep-alive
    Content-Length: 432100
    Pragma: no-cache
    Cache-Control: no-cache
    Sec-Fetch-Mode: cors
    Origin: null
    User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/76.0.3809.132 Safari/537.36
    Content-Type: multipart/form-data; boundary=----WebKitFormBoundary4X2oHxnVyC3gbFyk
    Accept: */*
    Sec-Fetch-Site: cross-site
    Accept-Encoding: gzip, deflate, br
    Accept-Language: zh-CN,zh;q=0.9,en;q=0.8
    
    ------WebKitFormBoundary4X2oHxnVyC3gbFyk
    Content-Disposition: form-data; name="file"; filename="Global  .png"
    Content-Type: image/png
            ...
    *** FIDDLER: RawDisplay truncated at 262144 characters. Right-click to disable truncation. ***
    
  • のうち、Content-Type:部分の内容はmultiad/form-dataである.boundary=----WebKitFormBoundary 4 X 2 oHxnVyC 3 g bFykここでは、multiipad/form-dataとはフォームデータの多くの部分から構成され、テキストデータとファイルなどのバイナリデータという意味です.boundary文字列は、要求ヘッダと要求体の
  • を分割する.
  • バイナリデータの一番後ろの文字の長さ情報
  • 複数のファイルのアップロード問題に遭遇すると、boundaryはいくつかの部分に分けられます.
  • Content-Type: multipart/form-data; boundary=${boundary} 
    
    --${boundary}
            ...
    --${boundary}--
    
    --${boundary}
            ...
    --${boundary}--
    
    進捗を監視
    xhr.uploadを使用してprogressイベントを追加することができ、Result.loaded/result.totalはアップロードされたサイズと全部のサイズをそれぞれ表します.タイマーを設計することでアップロード速度を計算し、データのアップロード進捗を可視化することができます.
    xhr.upload.addEventListener("progress", function(result) {
        console.log(result)
        console.log(result.loaded / result.total)
    }, false);
    
    四、バックグラウンド処理
    ファイルはバックグラウンドに送信されました.すぐにファイルの受信が行われます.ここではexpressとmultierの第三者モジュールを使って、ネットワーク要求と解析ファイルを処理します.
    const multer = require('multer')
    var objMulter = multer({dest: './www/upload/'});//        
    server.use(objMulter.any());//     
    
    //      req.files       
    
    中間処理をすると、ファイルはバイナリとして指定されたディレクトリに格納され、ファイルは重複しないハッシュ値をファイル名として生成し、複数ファイルのアップロードにファイルの衝突を防ぐ.しかし、私たちはファイルのアクセス性を保証するために、fsモジュールを使用してファイル名の拡張子を修正する必要があります.path.parse機能を使用して、req.filesのファイルフォーマットを分析することができます.
    server.post('/upload', function(req, res) {
    	console.log(pathLib.parse(req.files[0].originalname))
    	var newName = req.files[0].path + pathLib.parse(req.files[0].originalname).ext;
    
    	//   fs   rename             ,      
    	//rename('    ,   ,    ')
    	fs.rename(req.files[0].path, newName, function(err) {
    		if (err) {
    			res.send('    ')
    		} else {
    			res.send('    ')
    		}
    		res.end();
    	})
    })
    
    五、書類の再訪問
    ファイルをサーバーにアップロードしたら、ファイルの再アクセスが必要かもしれません.ファイルのサーバパスをファイルアップロードに成功したら、フロントエンドに戻すことができます.同時にサーバーにnginxまたは他のファイルリソースサーバを構成し、対応するパスコンテンツがアクセスできることを保証する.