Home  >  Article  >  Web Front-end  >  Handling file uploads with Node

Handling file uploads with Node

不言
不言Original
2018-07-07 17:15:493095browse

This article mainly introduces the use of Node to process file uploads, which has certain reference value. Now I share it with everyone. Friends in need can refer to it

Preface

In Web Development , file upload is a very common and important function. This article will introduce how to use Node to process uploaded files.

Requirement Analysis

Since front-end and back-end separation is very popular now, this article also directly adopts the front-end and front-end separation approach. The front-end interface is as follows:
Handling file uploads with Node

The user selects a file from the browser and clicks upload, which will initiate an http request to the server, and the server will store the received file on the server hard disk.

Front-end part

The ajax request library uses axios. In order to simplify the explanation, the front-end limits the uploaded file type to only pictures, and only one can be uploaded at a time. Interested friends can add it by themselves. , the code is as follows:

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>

Backend part

This is the focus of this article. In order to parse the file upload request in an efficient and smooth way, we first introduce formidable Library:

npm install formidable --save

formidable's Streaming Parser makes it an excellent choice for handling file uploads, meaning it can receive chunks of data as they are uploaded, parse them, And spit out specific parts, I believe friends who are familiar with the flow will understand it easily. This method is not only fast, but also does not cause memory expansion due to the need for a large amount of buffering. Even large files such as videos will not overwhelm the process.
First, we create the myImage file in the root directory to store the uploaded image (note: if it is not created, it will cause an upload error). Then, we create an IncomingForm instance form and set the storage path to the myImage folder. . The code is as follows:

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.')

After opening the http server with node app, upload a kitty.jpg on the front-end page, and we see that the console prints out the front-end The uploaded imgName attribute: kitty.jpg
Handling file uploads with Node

And, there is an additional picture in the myImage folder directory:
Handling file uploads with Node

Open it and see that it is correct It’s the kitty.jpg uploaded from the front end

File rename

We found that the default file name is not what we want, we want to change it to a file named after the current timestamp , the added function code is as follows:

  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)
  })

Uploaded again, and found that the name of the currently saved photo has changed to the format we want.
Handling file uploads with Node

Add upload progress

The progress event of Formidable can give the number of bytes received and the number of bytes expected to be received. We can use this to make a progress bar.
We add the following code to the above program. Every time a progress event is fired, the percentage will be calculated and output using console.log():

  form.on('progress', (bytesReceived, bytesExpected) => {
    var percent = Math.floor(bytesReceived / bytesExpected * 100)
    console.log(percent)
  })

Upload a picture again, and now the console will Printing out the progress shows:
Handling file uploads with Node

Of course, under normal circumstances, we want to send this progress back to the user's browser, which is suitable for any program that wants to upload large files. It's a great feature, and it's a task that's well-suited for Node. For example, using the WebSocket protocol, or a real-time module like Socket.IO. Regarding the use of websockets in Node, I will introduce it in a separate article later.

Error handling

Don’t forget to add error handling to the program at any time. If your program crashes at an important time, you may be spanked by your boss at least, or pulled out at worst. Sacrifice to heaven. Imagine that if the image uploaded by the user is very large and the user's network is still very slow, then the upload time will exceed the request timeout set in the front-end code by 2 seconds, and the server will crash. Don't believe it? Let's give it a try.
First, I chose a large picture, 5M, and used the chrome browser to set the browser network environment to slow 3g. The setting method is as follows:
f12 Open the developer tools and go to more tools-- network conditions
Handling file uploads with Node

Handling file uploads with Node

Click to upload, we see the following information on the server console, the server crashed:
Handling file uploads with Node

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

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

小结

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

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

相关推荐:

JS浏览器事件循环机制

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

The above is the detailed content of Handling file uploads with Node. For more information, please follow other related articles on the PHP Chinese website!

Statement:
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn