欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Node.js HTTP服務(wù)器中的文件、圖片上傳的方法

 更新時(shí)間:2019年09月23日 14:09:11   作者:潘鳳的博客  
這篇文章主要介紹了Node.js HTTP服務(wù)器中的文件、圖片上傳的方法,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧

HTTP協(xié)議中,multipart/form-data格式用于向服務(wù)器發(fā)送二進(jìn)制數(shù)據(jù),通過(guò)這一內(nèi)容類(lèi)型(Content-Type)可以實(shí)現(xiàn)文件、圖片的上傳。由于這種格式發(fā)送的是二進(jìn)制數(shù)據(jù),在服務(wù)器端接收和處理數(shù)據(jù)時(shí)會(huì)與其它內(nèi)容類(lèi)型有所有區(qū)別。

HTTP協(xié)議中的文件上傳

最早的HTTP協(xié)議中是不支持文件上傳的,在1995年制定的rfc1867規(guī)范中,在HTTP POST請(qǐng)求的內(nèi)容類(lèi)型Content-Type中擴(kuò)展了multipart/form-data類(lèi)型,該類(lèi)型用于向服務(wù)器發(fā)送二進(jìn)制數(shù)據(jù),以便支持文件的上傳。

POST上傳文件

我們通過(guò)form表單提交文件時(shí),會(huì)構(gòu)造類(lèi)似像下面這樣一個(gè)表單:

<form enctype="multipart/form-data" action="_URL_" method="POST">
 <input name="userfile1" type="file">
 <input type="submit" value="發(fā)送文件">
</form>

在使用form提交表單數(shù)據(jù)時(shí),默認(rèn)的編碼格式為application/x-www-form-urlencoded,上傳文件時(shí)需要通過(guò)enctype屬性將編碼方式設(shè)置為multipart/form-data。

HTTP數(shù)據(jù)提交與服務(wù)器數(shù)據(jù)解析

在包含請(qǐng)求體的請(qǐng)求中,提交的數(shù)據(jù)會(huì)按指定編碼類(lèi)型進(jìn)行編碼,而客戶(hù)端會(huì)按編碼方式設(shè)置請(qǐng)求頭中的Content-Type字段。
在一個(gè)application/x-www-form-urlencoded編碼的請(qǐng)求中,會(huì)設(shè)置一個(gè)如下的請(qǐng)求頭:

Content-Type:application/x-www-form-urlencoded

而用于文件上傳的編碼方式multipart/form-data,會(huì)設(shè)置一個(gè)如下的請(qǐng)求頭:

Content-type: multipart/form-data, boundary=AaB03x

服務(wù)器數(shù)據(jù)接收與解析

對(duì)于一個(gè)編碼方式為application/x-www-form-urlencoded的請(qǐng)求來(lái)說(shuō),會(huì)對(duì)提交內(nèi)容進(jìn)行URL編碼。服務(wù)器會(huì)收到類(lèi)似如下內(nèi)容:

POST / HTTP/1.1
Content-Type: application/x-www-form-urlencoded
Accept-Encoding: gzip, deflate
Host: itbilu.com
Content-Length: 23
Connection: Keep-Alive
Cache-Control: max-age=0

key1=value1&key2=value2

請(qǐng)求頭與請(qǐng)求體之間會(huì)有一個(gè)空行,服務(wù)器會(huì)對(duì)請(qǐng)求體以queryString的方式進(jìn)行解碼。

而對(duì)一個(gè)multipart/form-data的文件上傳請(qǐng)求來(lái)說(shuō),收到的內(nèi)容類(lèi)似如下:

POST / HTTP/1.1
Content-Type: multipart/form-data; boundary=----WebKitFormBoundaryYN9YYwO9ESipYBIx
Accept-Encoding: gzip, deflate
Host: itbilu.com
Content-Length: 22646
Connection: Keep-Alive
Cache-Control: max-age=0

------WebKitFormBoundaryoqBx9oYBhx4SF1YQ
Content-Disposition: form-data; name="myName"

itbilu.com
------WebKitFormBoundaryYN9YYwO9ESipYBIx
Content-Disposition: form-data; name="upload"; filename="41GiLecHO3L.jpg"
Content-Type: image/jpeg

����JFIF��C // 文件的二進(jìn)制數(shù)據(jù)
……
--------WebKitFormBoundaryYN9YYwO9ESipYBIx--

在請(qǐng)求頭的Content-Type字段中,除了編碼類(lèi)型為multipart/form-data描述外,還有一個(gè)boundary屬性,這是客戶(hù)端隨機(jī)生成的一個(gè)數(shù)據(jù)邊界描述。

如上所示,文件上傳時(shí)內(nèi)容是分段傳輸?shù)?,每一boundary表示一個(gè)fild(form表單控值)邊界。

如上面示例所示,上傳文件時(shí)除內(nèi)容描述外還包含一個(gè)的Content-Type文件MIME的描述,其后是一個(gè)空行和文件的二進(jìn)制數(shù)據(jù)。所有的表單數(shù)據(jù)結(jié)束后,會(huì)有一個(gè)”–”+boundary+”–”結(jié)束符。而服務(wù)器接收到數(shù)據(jù)后,同樣會(huì)根據(jù)boundary來(lái)進(jìn)行數(shù)據(jù)的接收和解析。

Node.js中處理圖片/文件上傳

Node.js中處理文件上傳的第三方模塊,本站曾經(jīng)介紹過(guò)使用formidable模塊處理文件上傳,下面簡(jiǎn)單介紹使用Node.js原生環(huán)境處理圖片上傳,上傳文件時(shí)也可以參考處理。

首先,使用Node.js的HTTP模塊創(chuàng)建一個(gè)HTTP服務(wù)器:

const http = require('http');
const fs = require('fs');
const util = require('util');
const querystring =require('querystring');

//用http模塊創(chuàng)建一個(gè)http服務(wù)端
http.createServer(function(req, res) {
 if (req.url == '/upload' && req.method.toLowerCase() === 'get') {
  //顯示一個(gè)用于文件上傳的form
  res.writeHead(200, {'content-type': 'text/html'});
  res.end(
   '<form action="/upload" enctype="multipart/form-data" method="post">'+
    '<input type="file" name="upload" multiple="multiple" />'+
    '<input type="submit" value="Upload" />'+
   '</form>'
  );
 } else if (req.url == '/upload' && req.method.toLowerCase() === 'post') {
  if(req.headers['content-type'].indexOf('multipart/form-data')!==-1)
   parseFile(req, res)
  } else {
   res.end('其它提交方式');
  }
}).listen(3000);

在這一步中,我們創(chuàng)建HTTP 服務(wù)器,當(dāng)GET請(qǐng)求時(shí),會(huì)加載一上用于文件上傳的form表單。上傳文件會(huì)通過(guò)POST方式提交到服務(wù)器,這時(shí)服務(wù)端會(huì)通過(guò)parseFile函數(shù)解析并保存文件,其解析代碼如下:

function parseFile (req, res) {
 req.setEncoding('binary');
 var body = '';  // 文件數(shù)據(jù)
 var fileName = ''; // 文件名
 // 邊界字符串
 var boundary = req.headers['content-type'].split('; ')[1].replace('boundary=','');
 req.on('data', function(chunk){
  body += chunk;
 });

 req.on('end', function() {
  var file = querystring.parse(body, '\r\n', ':')

  // 只處理圖片文件
  if (file['Content-Type'].indexOf("image") !== -1)
  {
   //獲取文件名
   var fileInfo = file['Content-Disposition'].split('; ');
   for (value in fileInfo){
    if (fileInfo[value].indexOf("filename=") != -1){
     fileName = fileInfo[value].substring(10, fileInfo[value].length-1);

     if (fileName.indexOf('\\') != -1){
      fileName = fileName.substring(fileName.lastIndexOf('\\')+1);
     }
     console.log("文件名: " + fileName);
    }
   }

   // 獲取圖片類(lèi)型(如:image/gif 或 image/png))
   var entireData = body.toString();
   var contentTypeRegex = /Content-Type: image\/.*/;

   contentType = file['Content-Type'].substring(1);

   //獲取文件二進(jìn)制數(shù)據(jù)開(kāi)始位置,即contentType的結(jié)尾
   var upperBoundary = entireData.indexOf(contentType) + contentType.length;
   var shorterData = entireData.substring(upperBoundary);

   // 替換開(kāi)始位置的空格
   var binaryDataAlmost = shorterData.replace(/^\s\s*/, '').replace(/\s\s*$/, '');

   // 去除數(shù)據(jù)末尾的額外數(shù)據(jù),即: "--"+ boundary + "--"
   var binaryData = binaryDataAlmost.substring(0, binaryDataAlmost.indexOf('--'+boundary+'--'));

   // 保存文件
   fs.writeFile(fileName, binaryData, 'binary', function(err) {
    res.end('圖片上傳完成');
   });
  } else {
   res.end('只能上傳圖片文件');
  }
 });
}

req是一個(gè)IncomingMessage對(duì)象,而該對(duì)象又實(shí)現(xiàn)了ReadableStream,所以我們可以用流的方式來(lái)接收數(shù)據(jù)。數(shù)據(jù)接收完成了,按rfc1867規(guī)范進(jìn)行了數(shù)據(jù)處理,并通過(guò)fs模塊保存了文件。

以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。

相關(guān)文章

  • 使用koa2創(chuàng)建web項(xiàng)目的方法步驟

    使用koa2創(chuàng)建web項(xiàng)目的方法步驟

    這篇文章主要介紹了使用koa2創(chuàng)建web項(xiàng)目的方法步驟,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2019-03-03
  • nodeJS微信分享

    nodeJS微信分享

    這篇文章主要為大家詳細(xì)介紹了nodeJS微信分享的相關(guān)資料,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2017-12-12
  • nodejs中各種加密算法的實(shí)現(xiàn)詳解

    nodejs中各種加密算法的實(shí)現(xiàn)詳解

    這篇文章主要給大家介紹了關(guān)于nodejs中各種加密算法的實(shí)現(xiàn)方法,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家學(xué)習(xí)或者使用nodejs具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2019-07-07
  • 使用node.js半年來(lái)總結(jié)的 10 條經(jīng)驗(yàn)

    使用node.js半年來(lái)總結(jié)的 10 條經(jīng)驗(yàn)

    從3月初來(lái)到帝都某創(chuàng)業(yè)公司的服務(wù)器團(tuán)隊(duì)實(shí)習(xí),到現(xiàn)在已接近半年的時(shí)間。PS: 已轉(zhuǎn)正,服務(wù)器端用的 Node。
    2014-08-08
  • node.js應(yīng)用后臺(tái)守護(hù)進(jìn)程管理器Forever安裝和使用實(shí)例

    node.js應(yīng)用后臺(tái)守護(hù)進(jìn)程管理器Forever安裝和使用實(shí)例

    這篇文章主要介紹了node.js應(yīng)用后臺(tái)守護(hù)進(jìn)程管理器Forever安裝和使用實(shí)例,forever可以看做是一個(gè)nodejs的守護(hù)進(jìn)程,能夠啟動(dòng),停止,重啟我們的app應(yīng)用,需要的朋友可以參考下
    2014-06-06
  • 詳解nodejs內(nèi)置模塊

    詳解nodejs內(nèi)置模塊

    這篇文章主要介紹了nodejs內(nèi)置模塊,對(duì)nodejs感興趣的同學(xué),可以參考下
    2021-05-05
  • Nodejs中自定義事件實(shí)例

    Nodejs中自定義事件實(shí)例

    這篇文章主要介紹了Nodejs中自定義事件實(shí)例,比較簡(jiǎn)單的一個(gè)例子,需要的朋友可以參考下
    2014-06-06
  • Nodejs小文件拷貝復(fù)制和大文件拷貝復(fù)制方法代碼

    Nodejs小文件拷貝復(fù)制和大文件拷貝復(fù)制方法代碼

    NodeJS提供了基本的文件操作API,但是像文件拷貝復(fù)制這種高級(jí)功能就沒(méi)有提供,因此我們先拿文件拷貝程序練手,文件拷貝復(fù)制是在Node.js中常見(jiàn)的操作之一,它允許我們將一個(gè)文件的內(nèi)容復(fù)制到另一個(gè)文件中
    2023-11-11
  • Koa2微信公眾號(hào)開(kāi)發(fā)之消息管理

    Koa2微信公眾號(hào)開(kāi)發(fā)之消息管理

    這篇文章主要介紹了Koa2微信公眾號(hào)開(kāi)發(fā)之消息管理,這一節(jié)我們就來(lái)看看公眾號(hào)的消息管理。并實(shí)現(xiàn)一個(gè)自動(dòng)回復(fù)功能,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2018-05-05
  • 使用Node操作MySQL的兩種方式

    使用Node操作MySQL的兩種方式

    本文將介紹如何在?Node.js?應(yīng)用中使用?mysql2?和?TypeORM?兩種方式操作?MySQL?數(shù)據(jù)庫(kù),文中通過(guò)代碼示例介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)有一定的幫助,需要的朋友可以參考下
    2024-05-05

最新評(píng)論