Node의 http 모듈이 파일 업로드를 처리하는 방법에 대한 간략한 분석

青灯夜游
풀어 주다: 2023-03-09 19:37:01
앞으로
1670명이 탐색했습니다.

Node.js의 http 모듈을 사용하여 파일 업로드를 처리하는 방법은 무엇입니까? 다음 글에서는 프런트 엔드에서 업로드한 파일을 서버 측에서 처리하는 방법을 살펴보겠습니다. 모든 분들께 도움이 되길 바랍니다!

Node의 http 모듈이 파일 업로드를 처리하는 방법에 대한 간략한 분석

요청 데이터 보기

지금 우리가 서버로 보내는 데이터가 아래 그림과 같다면, 일반 필드 정보 이름과 이미지 파일 파일이 포함되어 있습니다. 코드>:<code>name 以及一个图片文件 file

Node의 http 모듈이 파일 업로드를 처리하는 방법에 대한 간략한 분석

我们先来看看如何在服务器接收到文件上传的数据,并在调试控制台打印查看:

const http = require(&#39;http&#39;)
const server = http.createServer((req, res) => {
  req.setEncoding(&#39;binary&#39;)
  req.on(&#39;data&#39;, data => {
    console.log(data)
  })
  req.on(&#39;end&#39;, () => {
    console.log(&#39;上传结束&#39;)
    res.end(&#39;上传成功&#39;)
  })
})
server.listen(3010, () => console.log(&#39;服务器开启&#39;))
로그인 후 복사

想要能看懂打印的结果,我们通过 req.setEncoding(&#39;binary&#39;) 设置了字符编码为 &#39;binary&#39;,这样得到的数据就不是 buffer 对象而是 ASCII 编码后的字符串,我们就可以使用一些字符串的方法来处理数据了。

但是当文件大小比较大时,直接通过在命令行输入 node 或 nodemon 来运行代码,得到的数据无法完全在控制台展示。所以我们可以在要打印请求数据的地方打上断点,通过 debugger 的模式来运行代码:

Node의 http 모듈이 파일 업로드를 처리하는 방법에 대한 간략한 분석

点击 "运行和调试" 后,vs code 就会帮我们把服务器运行起来了:

Node의 http 모듈이 파일 업로드를 처리하는 방법에 대한 간략한 분석

之后当我们发送了上传的请求,再点击下图右上角的 "单步跳过",就可以看到请求的数据了 —— 那些可以被 ASCII 编译的信息,比如英文字母,可以直接看到了,而图片的数据则是一堆乱码:

Node의 http 모듈이 파일 업로드를 처리하는 방법에 대한 간략한 분석

接下来就是处理获取的请求数据,将里面的图片数据截取出来然后通过写入流生成图片。

处理文件(图片)数据

获取图片数据

因为可读流&#39;data&#39; 事件一次最多读取 64kb 的数据,当图片比较大时,可能会触发多次,所以我们定义变量 reqData 来存储请求发来的数据:

let reqData = &#39;&#39;
req.on(&#39;data&#39;, data => {
  reqData += data
})
req.on(&#39;end&#39;, () => {
  console.log(reqData) // 在这行打断点
  res.end(&#39;上传成功&#39;)
})
로그인 후 복사

req 触发了 &#39;end&#39; 事件说明请求数据读取完毕,如果在上列代码的第 6 行 console.log(reqData) 处打个断点,然后查看 reqData,得到的数据如下:

Node의 http 모듈이 파일 업로드를 처리하는 방법에 대한 간략한 분석

图片的数据应该是 image/pngrnrnrn----------------------------158329774739626517859573--rn 中间这段。我们可以去获取图片数据的起(imgDataStartIndex)止(imgDataEndIndex)位置的 index,然后使用 substring() 做个截取,最后再使用 trim() 方法去除首位的空格 rn

const imgType = &#39;image/png&#39;
const imgDataStartIndex = reqData.indexOf(imgType) + imgType.length
const imgDataEndIndex = reqData.indexOf(`--${boundary}--`)
const imgData = reqData.substring(imgDataStartIndex, imgDataEndIndex).trim()
로그인 후 복사

获取分隔符 boundary

--------------------------158329774739626517859573是客户端随机生成的,用于分割表单里的每段数据的分隔符(boundary),在每个表单项的开头和结尾都有,并且在开头处的前面都会加上两个减号 --,在整个表单数据结束处的末尾也会加上两个减号。查看请求头:

Node의 http 모듈이 파일 업로드를 처리하는 방법에 대한 간략한 분석

可以发现在 content-type 里定义了boundary,于是我们可以使用如下方法获取分隔符:

const boundary = req.headers[&#39;content-type&#39;].split(&#39;boundary=&#39;)[1]
로그인 후 복사

生成图片

获取到了图片数据 imgData 后,就可以通过 fswriteFile() 写入文件生成图片了:

fs.writeFile(&#39;./img.png&#39;, imgData, &#39;binary&#39;, err => {
  if (!err) console.log(&#39;图片写入成功&#39;)
})
로그인 후 복사

注意需要在第三个参数传入&#39;binary&#39; 来设定 encoding

Node의 http 모듈이 파일 업로드를 처리하는 방법에 대한 간략한 분석

먼저 서버에 업로드된 파일 데이터를 받아 디버깅 콘솔에 인쇄하는 방법을 살펴보겠습니다.
const http = require('http')
const fs = require('fs')

const server = http.createServer((req, res) => {
  req.setEncoding(&#39;binary&#39;)
  const boundary = req.headers[&#39;content-type&#39;].split(&#39;boundary=&#39;)[1]
  let reqData = ''
  req.on(&#39;data&#39;, data => {
    reqData += data
  })
  req.on(&#39;end&#39;, () => {
    const imgType = 'image/png'
    const imgDataStartIndex = reqData.indexOf(imgType) + imgType.length
    const imgDataEndIndex = reqData.indexOf(`--${boundary}--`)
    const imgData = reqData.substring(imgDataStartIndex, imgDataEndIndex).trim()
    fs.writeFile('./img.png', imgData, &#39;binary&#39;, err => {
      if (!err) console.log('图片写入成功')
    })
    res.end('上传成功')
  })
})

server.listen(3010, () => console.log('服务器开启'))
로그인 후 복사
로그인 후 복사

인쇄된 결과를 이해하려면 req.setEncoding(' 바이너리') 문자 인코딩을 '바이너리'로 설정하여 얻은 데이터가 버퍼 개체가 아니라 ASCII로 인코딩된 문자열이 되도록 일부 문자열 메서드를 사용하여 데이터를 처리할 수 있습니다. .

그러나 파일 크기가 상대적으로 큰 경우 명령줄에 node 또는 nodemon을 직접 입력하여 코드를 실행해도 얻은 데이터가 콘솔에 완전히 표시되지 않습니다. 따라서 요청 데이터를 인쇄하려는 위치에 중단점을 배치하고 디버거 모드를 통해 코드를 실행할 수 있습니다. 🎜🎜🎜🎜"실행 및 디버그"를 클릭하면 vs 코드가 서버 실행에 도움이 됩니다. 🎜🎜Node의 http 모듈이 파일 업로드를 처리하는 방법에 대한 간략한 분석🎜🎜이후 업로드 요청을 보내면 "를 클릭하세요. 요청한 데이터를 보려면 아래 그림의 오른쪽 상단에 있는 "Single Step Skip"을 클릭하세요. 영문자와 같이 ASCII로 컴파일할 수 있는 정보는 바로 볼 수 있지만, 그림의 데이터는 왜곡된 문자 덩어리입니다. 🎜🎜Node의 http 모듈이 파일 업로드를 처리하는 방법에 대한 간략한 분석🎜🎜연결 다음 단계는 획득한 요청 데이터를 처리하고, 내부의 이미지 데이터를 가로채고, 스트림에 기록하여 이미지를 생성하는 것입니다. 🎜🎜🎜파일(이미지) 데이터 처리 중🎜🎜🎜🎜이미지 데이터 가져오기🎜🎜🎜읽기 가능한 스트림'data' 이벤트는 최대 64kb까지 읽을 수 있습니다. a time 그림이 비교적 큰 경우 데이터가 여러 번 트리거될 수 있으므로 요청에 의해 전송된 데이터를 저장하기 위해 reqData 변수를 정의합니다. 🎜rrreee🎜req</code > <code >'end' 트리거 이벤트 설명은 요청한 데이터를 읽었다는 것입니다. 위 코드 console.log(reqData)의 6번째 줄에 중단점을 설정하면, 그런 다음 reqData 를 보면 얻은 데이터는 다음과 같습니다: 🎜🎜Node의 http 모듈이 파일 업로드를 처리하는 방법에 대한 간략한 분석🎜🎜사진의 데이터는 image/pngrnrnrn----------이어야 합니다. ----------- -------158329774739626517859573--rn 중간 단락입니다. 이미지 데이터의 시작(imgDataStartIndex)과 끝(imgDataEndIndex) 위치의 인덱스를 가져온 다음 substring()을 사용하여 가로채고 마지막으로 trim() 메서드를 사용하여 선행 공백 rn을 제거합니다. 🎜rrreee

🎜Get 구분자 경계🎜

🎜-------------158329774739626517859573는 클라이언트에 의해 무작위로 생성되어 사용됩니다. 양식의 각 단락을 분할하려면 각 양식 항목의 시작과 끝 부분에 데이터 구분 기호(경계)가 있으며 시작 앞과 끝 부분에 두 개의 빼기 기호 --가 추가됩니다. 전체 양식 데이터의 끝에는 두 개의 빼기 기호도 있습니다. 요청 헤더 보기: 🎜🎜Node의 http 모듈이 파일 업로드를 처리하는 방법에 대한 간략한 분석🎜🎜content-type경계가 정의되어 있음을 확인할 수 있으므로 다음 방법을 사용하여 구분자를 가져올 수 있습니다: 🎜rrreee🎜🎜이미지 생성🎜🎜🎜이미지 데이터 imgData를 얻은 후 fswriteFile()은 파일을 작성하여 이미지를 생성합니다. 🎜rrreee 🎜인코딩을 설정하려면 'binary'의 세 번째 Pass 매개변수에 있어야 합니다. 🎜🎜🎜Summary🎜🎜🎜이제 코드는 다음과 같이 요약됩니다.🎜
const http = require('http')
const fs = require('fs')

const server = http.createServer((req, res) => {
  req.setEncoding(&#39;binary&#39;)
  const boundary = req.headers[&#39;content-type&#39;].split(&#39;boundary=&#39;)[1]
  let reqData = ''
  req.on(&#39;data&#39;, data => {
    reqData += data
  })
  req.on(&#39;end&#39;, () => {
    const imgType = 'image/png'
    const imgDataStartIndex = reqData.indexOf(imgType) + imgType.length
    const imgDataEndIndex = reqData.indexOf(`--${boundary}--`)
    const imgData = reqData.substring(imgDataStartIndex, imgDataEndIndex).trim()
    fs.writeFile('./img.png', imgData, &#39;binary&#39;, err => {
      if (!err) console.log('图片写入成功')
    })
    res.end('上传成功')
  })
})

server.listen(3010, () => console.log('服务器开启'))
로그인 후 복사
로그인 후 복사

上述代码能够成功运行还有一些限制,比如只能处理单文件上传,且文件需要是 png 格式的图片,并且放在表单最后一项。文章的目的在于简单了解使用 node 的 http 模块搭建的服务器大体上是如何处理上传文件的请求的,为将来深入学习其它基于 http 模块的框架(express.js、koa.js 等)打好基础。

更多node相关知识,请访问:nodejs 教程

위 내용은 Node의 http 모듈이 파일 업로드를 처리하는 방법에 대한 간략한 분석의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

관련 라벨:
원천:juejin.cn
본 웹사이트의 성명
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.
인기 튜토리얼
더>
최신 다운로드
더>
웹 효과
웹사이트 소스 코드
웹사이트 자료
프론트엔드 템플릿
회사 소개 부인 성명 Sitemap
PHP 중국어 웹사이트:공공복지 온라인 PHP 교육,PHP 학습자의 빠른 성장을 도와주세요!