>  기사  >  웹 프론트엔드  >  Node로 파일 업로드 처리

Node로 파일 업로드 처리

不言
不言원래의
2018-07-07 17:15:493086검색

이 글은 주로 파일 업로드를 처리하기 위한 Node의 사용을 소개합니다. 이제 여러분과 공유합니다. 도움이 필요한 친구들이 참고할 수 있습니다.

머리말

웹 개발에서 파일 업로드는 매우 일반적이며 매우 일반적인 중요한 기능입니다. 이 글에서는 Node를 사용하여 업로드된 파일을 처리하는 방법을 소개합니다.

요구사항 분석

현재 프론트엔드와 백엔드 분리가 매우 대중화되어 있으므로 이 글에서도 프런트엔드와 프론트엔드 분리 방법을 직접 채택합니다. 프런트 엔드 인터페이스는 다음과 같습니다: 前后端分离的做法。前端界面如下:
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

사용자가 브라우저에서 파일을 선택하고 클릭하여 업로드하면 서버에 http 요청이 시작되고 서버는 수신된 파일을 서버의 하드 디스크에 저장합니다.

프런트엔드 부분

ajax 요청 라이브러리는 설명을 단순화하기 위해 업로드되는 파일 형식을 이미지로만 제한하고 관심 있는 친구는 한 번에 하나만 업로드할 수 있습니다.

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

이 글의 초점은 파일 업로드 요청을 효율적이고 원활하게 분석하기 위해 먼저 formidable을 소개합니다. 라이브러리: Node로 파일 업로드 처리rrreee

formidable의 스트리밍 파서는 파일 업로드를 처리하는 데 탁월한 선택입니다. 즉, 업로드되는 데이터 블록을 수신하여 구문 분석하고 특정 부분을 뱉어낼 수 있다는 뜻입니다. 스트림을 사용하면 잘 이해할 것입니다. 이 방법은 속도가 빠를 뿐만 아니라, 대용량 버퍼링이 필요하기 때문에 메모리 확장이 발생하지 않으며, 동영상과 같은 대용량 파일도 프로세스에 부담을 주지 않습니다.

먼저 업로드된 이미지를 저장하기 위해 루트 디렉터리에 myImage 파일을 생성합니다(참고: 생성되지 않으면 업로드 오류가 발생합니다). 그런 다음 IncomingForm 인스턴스 양식을 생성하고 저장 경로를 myImage로 설정합니다. 접는 사람. 코드는 다음과 같습니다.
rrreeeNode로 파일 업로드 처리 node app으로 http 서버를 연 후 프런트 엔드 페이지에 kitty.jpg를 업로드하면 콘솔이 인쇄되는 것을 볼 수 있습니다. imgname 속성으로 업로드된 파일을 꺼냅니다: kitty.jpg

957684296-5B403572708_ARTICLEX [1].jpg🎜🎜그리고 myImage 폴더에 추가 사진이 있습니다: 🎜Node로 파일 업로드 처리🎜🎜열어서 프론트엔드에서 업로드한 kitty.jpg인지 확인하세요 🎜🎜파일 이름이 변경되었습니다. 🎜🎜이 기본 파일 이름은 우리가 원하는 이름이 아닙니다. 추가된 기능 코드는 다음과 같습니다. 🎜rrreee🎜다시 업로드하세요. 현재 저장된 사진의 이름이 원하는 형식이 되었는지 확인합니다. 🎜🎜🎜업로드 진행률 추가🎜🎜Formidable의 진행 이벤트는 수신된 바이트 수와 수신될 것으로 예상되는 바이트 수를 제공할 수 있습니다. 이를 사용하여 진행률 표시줄을 만들 수 있습니다. 🎜위 프로그램에 다음 코드를 추가합니다. 진행 이벤트가 발생할 때마다 백분율이 계산되어 console.log()를 사용하여 출력됩니다. 🎜rrreee🎜 사진을 다시 업로드하면 이제 콘솔이 진행 상황을 인쇄합니다. 디스플레이: 🎜🎜🎜물론 일반적인 상황에서는 이 진행 상황을 사용자의 브라우저로 다시 보내고 싶습니다. 이는 대용량 파일을 업로드하려는 모든 프로그램에 훌륭한 기능이며 매우 적합한 용도입니다. 작업 완료 노드별. 예를 들어 WebSocket 프로토콜을 사용하거나 Socket.IO와 같은 실시간 모듈을 사용하는 경우 Node에서 웹소켓을 사용하는 방법에 대해서는 나중에 별도로 소개하겠습니다. 🎜🎜오류 처리🎜🎜언제든지 프로그램에 오류 처리를 추가하는 것을 잊지 마세요. 중요한 순간에 프로그램이 충돌하면 최소한 상사에게 맞을 수도 있고, 최악의 경우 신을 숭배하기 위해 끌려갈 수도 있습니다. . 사용자가 업로드한 이미지가 매우 크고 사용자의 네트워크가 여전히 매우 느린 경우 업로드 시간이 프런트엔드 코드에 설정된 요청 제한 시간을 2초 초과하여 서버가 충돌할 것이라고 상상해 보십시오. 믿어요? 한번 시도해 봅시다. 🎜먼저 5M라는 큰 사진을 선택했고, 크롬 브라우저를 이용해 브라우저 네트워크 환경을 3g로 느리게 설정했습니다. 설정 방법은 다음과 같습니다. 🎜f12에서 개발자 도구를 열고 추가 도구--네트워크 조건으로 이동합니다. 🎜🎜 🎜🎜🎜🎜🎜업로드하려면 클릭하세요. 서버 콘솔에 다음 정보가 표시되고 서버가 충돌합니다. 🎜🎜🎜

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

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

小结

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

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

相关推荐:

JS浏览器事件循环机制

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

위 내용은 Node로 파일 업로드 처리의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.