Node を使用したファイルのアップロードの処理

不言
リリース: 2018-07-07 17:15:49
オリジナル
3089 人が閲覧しました

この記事では、ファイルのアップロードを処理するための Node の使用法を主に紹介します。これには、必要な友人が参照できるように共有します。非常に一般的な問題。この記事では、アップロードされたファイルを Node を使用して処理する方法を紹介します。

要件分析

現在、フロントエンドとバックエンドの分離が非常に一般的であるため、この記事でも フロントエンドとフロントエンドの分離 アプローチを直接採用しています。フロントエンド インターフェイスは次のとおりです:

 1242696478-5b40279f4c64c_articlex[1 ].jpg

ユーザーがブラウザからファイルを選択し、クリックしてアップロードすると、サーバーへの http リクエストが開始され、サーバーは受信したファイルをサーバーのハードディスクに保存します。

前后端分离的做法。前端界面如下:
Node を使用したファイルのアップロードの処理

用户从浏览器中选择文件,点击上传,将发起http请求到服务器,服务器将接受到的文件存储在服务器硬盘中。

前端部分

ajax请求库采用axios,为了简化说明,前端限制上传的文件类型只能为图片,且一次只能上传一张,有兴趣的朋友可以自行补充,代码如下:

nbsp;html>


  <meta>
  <title>Title</title>
  <script></script>


  <input>
  <button>上传</button>

  <script>
    let file = &#39;&#39;
    let fileName = &#39;&#39;

    function submit() {
      let data = new FormData()
      data.append(&#39;imgName&#39;, fileName)
      data.append(&#39;img&#39;, file)

      axios({
        method: &#39;post&#39;,
        timeout: 2000,
        url: &#39;http://localhost:3000/postApi&#39;,
        data: data
      })
        .then(response => {
          console.log(response.data)
        })
        .catch(error => {
          console.log(error)
        })
    }

    function changeImg(e) {
      file = e.target.files.item(0)
      // 如果不选择图片
      if (file === null) {
        return
      }
      fileName = file.name
    }
  </script>

ログイン後にコピー

后端部分

这是本文要介绍的重点,为了用高效流畅的方式来解析文件上传请求,我们先引入formidable库:

npm install formidable --save
ログイン後にコピー

formidable的流式解析器让它成为了处理文件上传的绝佳选择,也就是说它能随着数据块的上传接收它们,解析它们,并吐出特定的部分,相信熟悉流的朋友会很好理解。这种方式不仅快,还不会因为需要大量缓冲而导致内存膨胀,即便像视频这种大型文件,也不会把进程压垮。
首先,我们在根目录下创建myImage文件,用于存放上传的图片(注意:如果没有创建,会导致上传报错),接着,我们创建一个IncomingForm实例form,并且设置存放路径为myImage文件夹。代码如下:

var http = require('http')
var formidable = require('formidable')

var server = http.createServer(function(req, res){
  // 1 设置cors跨域
  res.setHeader('Access-Control-Allow-Origin', '*')
  res.setHeader('Access-Control-Allow-Headers', 'Content-Type')
  res.setHeader('Content-Type', 'application/json')

  // 2
  switch (req.method) {
    case 'OPTIONS':
      res.statusCode = 200
      res.end()
      break
    case 'POST':
      upload(req, res)
      break
  }
})

function upload(req, res) {
  // 1 判断
  if (!isFormData(req)) {
    res.statusCode = 400
    res.end('错误的请求, 请用multipart/form-data格式')
    return
  }

  // 2 处理
  var form = new formidable.IncomingForm()
  form.uploadDir = './myImage'
  form.keepExtensions = true

  form.on('field', (field, value) => {
    console.log(field)
    console.log(value)
  })
  form.on('end', () => {
    res.end('上传完成!')
  })

  form.parse(req)
}

function isFormData(req) {
  let type = req.headers['content-type'] || ''
  return type.includes('multipart/form-data')
}

server.listen(3000)
console.log('port is on 3000.')
ログイン後にコピー

node app开启http服务器后,在前端页面中上传一张kitty.jpg,我们看到控制台打印出了前端上传的imgName属性:kitty.jpg
Node を使用したファイルのアップロードの処理

并且,myImage文件夹目录下多了一张图片:
Node を使用したファイルのアップロードの処理

打开一看,正是从前端上传的那张kitty.jpg

文件改名

我们发现,这个默认的文件名称并不是我们想要的,我们想改成以当前时间戳命名的文件,添加的功能代码如下:

  var fs = require('fs')

  form.on('file', (name, file) => {
    // 重命名文件
    let types = file.name.split('.')
    let suffix = types[types.length - 1]
    fs.renameSync(file.path, './myImage/' + new Date().getTime() + '.' + suffix)
  })
ログイン後にコピー

再次上传,发现现在存的照片名称已经变成我们想要的格式了。
Node を使用したファイルのアップロードの処理

添加上传进度

Formidable的progress事件能给出收到的字节数,以及期望收到的字节数。我们可以借助这个做出一个进度条。
我们为上面的程序添加下面的代码,每次有progress事件激发,就会计算百分比并用console.log()输出:

  form.on('progress', (bytesReceived, bytesExpected) => {
    var percent = Math.floor(bytesReceived / bytesExpected * 100)
    console.log(percent)
  })
ログイン後にコピー

再次上传一张图片,现在控制台已经会打印出进度显示了:
Node を使用したファイルのアップロードの処理

当然,一般情况下,我们是要把这个进度传回到用户的浏览器中去,这对于任何想要上传大型文件的程序来说是个很棒的特性,并且这是个很适合用Node完成的任务。比如说用WebSocketフロントエンド部分

ajaxリクエストライブラリはaxiosを使用します。説明を簡単にするために、フロントエンドはアップロードするファイルの種類を画像のみに制限し、興味のある友達は一度に1つだけを追加できます。コードは次のとおりです。

  // 加上错误处理,防止用户网络慢,或者取消上传,导致服务器崩掉
  form.on('error', err => {
    console.log(err)
    res.statusCode = 500
    res.end('服务器内部错误!')
  })
ログイン後にコピー
ログイン後にコピー

最後の部分

これがこの記事の焦点です。ファイルのアップロード リクエストを効率的かつスムーズに解析するために、最初に formidable を導入します。ライブラリ:
rrreeeNode を使用したファイルのアップロードの処理formidable の ストリーミング パーサー は、ファイルのアップロードを処理するための優れた選択肢です。つまり、アップロード時にデータ ブロックを受け取り、解析し、特定の部分を吐き出すことができます。ストリームを使えばよくわかります。この方法は高速であるだけでなく、大量のバッファリングが必要なため、ビデオなどの大きなファイルでもプロセスに負荷がかかることはありません。

まず、アップロードされた画像を保存するための myImage ファイルをルート ディレクトリに作成します (注: 作成されていない場合、アップロード エラーが発生します)。次に、IncomingForm インスタンス フォームを作成し、ストレージ パスを myImage に設定します。フォルダ。コードは次のとおりです。

rrreeeNode を使用したファイルのアップロードの処理 node app で http サーバーを開いた後、フロントエンド ページに kitty.jpg をアップロードします。コンソールに出力されることがわかります。フロントエンドによってアップロードされたファイルの imgname 属性: kitty.jpg

957684296-5B403572708_ARTICLEX [1].jpg


そして、myImage フォルダーに追加の画像があります: Node を使用したファイルのアップロードの処理Node を使用したファイルのアップロードの処理

🎜それを開いて、正面からアップロードされたkitty.jpgであることを確認してくださいend🎜🎜ファイルの名前が変更されました🎜🎜このデフォルトのファイル名は私たちが望むものではないことがわかりました。追加された関数コードは次のとおりです: 🎜rrreee🎜それをアップロードします。もう一度クリックすると、保存された写真の名前が希望どおりになっていることがわかります。 🎜Node を使用したファイルのアップロードの処理🎜🎜アップロードの進行状況を追加🎜🎜Formidable の進行状況イベントは、受信したバイト数と受信が予想されるバイト数を与えることができます。これを使用して進行状況バーを作成できます。 🎜次のコードを上記のプログラムに追加します。進捗イベントが発生するたびに、console.log() を使用してパーセンテージが計算され、出力されます。 🎜rrreee🎜 画像を再度アップロードすると、コンソールが進捗状況を出力します。表示: 🎜1878580068-5b403beec5119_articlex[1]。 jpg🎜🎜 もちろん、通常の状況では、この進行状況をユーザーのブラウザに送り返したいと考えます。これは、大きなファイルをアップロードするプログラムにとって優れた機能であり、非常に適切な用途です。タスクは完了しました。ノードによる。たとえば、WebSocket プロトコルを使用するか、Socket.IO のようなリアルタイム モジュールを使用します。Node での WebSocket の使用については、後ほど別の記事で紹介します。 🎜🎜エラー処理🎜🎜 重要なときにプログラムにエラー処理を追加することを忘れないでください。場合によっては、少なくとも上司に尻を叩かれるか、最悪の場合、神を崇拝するために引き抜かれる可能性があります。 。ユーザーがアップロードした画像が大きく、ユーザーのネットワークが依然として非常に遅い場合、アップロード時間がフロントエンド コードで設定されたリクエスト タイムアウトを 2 秒超えて、サーバーがクラッシュすることを想像してください。それ?やるだけやってみよう。 🎜まず、大きな画像(5M)を選択し、Chromeブラウザを使用してブラウザのネットワーク環境を低速3Gに設定します。設定方法は次のとおりです。 🎜f12で開発者ツールを開き、その他のツール-ネットワーク条件に移動します。 🎜🎜 🎜🎜🎜🎜🎜 クリックしてアップロードすると、サーバー コンソールに次の情報が表示されます。サーバーがクラッシュしました: 🎜🎜🎜

所以,最后我们加上了错误处理,代码如下:

  // 加上错误处理,防止用户网络慢,或者取消上传,导致服务器崩掉
  form.on('error', err => {
    console.log(err)
    res.statusCode = 500
    res.end('服务器内部错误!')
  })
ログイン後にコピー
ログイン後にコピー

小结

现在,相信你已经学会了如何用Node处理文件上传了,结合前面的那篇用Node提供静态文件服务的文章,你是不是能够自己摸索着去尝试做一些有趣的事情了呢?

以上就是本文的全部内容,希望对大家的学习有所帮助,更多相关内容请关注PHP中文网!

相关推荐:

JS浏览器事件循环机制

小程序中使用ECharts 异步加载数据

以上がNode を使用したファイルのアップロードの処理の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

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