首頁  >  文章  >  web前端  >  淺析用Node建立一個簡單的HTTP伺服器

淺析用Node建立一個簡單的HTTP伺服器

青灯夜游
青灯夜游轉載
2022-12-05 18:35:222021瀏覽

怎麼使用NodeJS建立HTTP伺服器?以下這篇文章跟大家介紹一下使用Node建立一個簡單的HTTP伺服器的方法,希望對大家有幫助!

淺析用Node建立一個簡單的HTTP伺服器

1. 使用Node.js直接執行JavaScript腳本

node.js基於Chromev8引擎運行js程式碼,因此我們可以擺脫瀏覽器環境,直接在控制台中執行js程式碼,例如下面這個hello world程式碼

console.log('hello world');

控制台中直接使用node即可執行

淺析用Node建立一個簡單的HTTP伺服器


2. 建立一個簡單的HTTP伺服器

node.js的內建模組http提供了基本的http服務的能力,基於CommonJS規範,我們可以使用require導入http模組進行使用http模組中有一個createServer函數能夠讓我們建立一個http伺服器 其接收一個回呼函數作為參數,這個回呼函數接收兩個參數 -- requestresponse。 【相關教學推薦:nodejs影片教學

  • request包含所有客戶端請求的信息,例如url、請求頭header、請求方式和請求體等
  • response主要用於傳回訊息給客戶端,封裝了一些操作回應體相關的操作,例如 response.writeHead方法就可以讓我們自訂返回體的頭部資訊和狀態碼

當我們將回應體處理好了之後,呼叫response.end() 方法就可以將回應體傳送給客戶端 使用createServer函數只是幫我們建立了一個Server對象,並沒有讓其開啟監聽,我們還需要呼叫server對象的listen方法才可以進行監聽,真正作為一個伺服器開始運行

  • listen方法的第一個參數是監聽的連接埠號,第二個參數則是綁定的主機ip,第三個參數是一個回呼函數,會被http模組非同步調用,當遇到錯誤的時候,就能夠在這個回呼函數的第一個參數中取得到拋出的異常,我們可以選擇對異常進行處理,讓我們的伺服器更加健壯

#下面是使用http模組建立一個簡單伺服器的範例

const { createServer } = require('http');
const HOST = 'localhost';
const PORT = '8080';

const server = createServer((req, resp) => {
  // the first param is status code it returns  
  // and the second param is response header info
  resp.writeHead(200, { 'Content-Type': 'text/plain' });  
  
  console.log('server is working...');  
  
  // call end method to tell server that the request has been fulfilled
  resp.end('hello nodejs http server');
});

server.listen(PORT, HOST, (error) => {  
if (error) {  
  console.log('Something wrong: ', error);   
   return;
  }  
  console.log(`server is listening on http://${HOST}:${PORT} ...`);
});

可以直接嘗試用node運行它,創造一個屬於你的伺服器!伺服器執行後,瀏覽器造訪http://localhost:8080即可存取到這個伺服器

淺析用Node建立一個簡單的HTTP伺服器

也可以使用nodemon運行它,這樣當我們的程式碼改變的時候就不需要手動終止程式再重新運行了

npm i -g nodemon

建議全域安裝它,這樣就可以直接使用,不需要透過npx nodemon去使用 使用也很簡單,直接將node指令改成nodemon指令即可

nodemon http-server.js

淺析用Node建立一個簡單的HTTP伺服器


##3 . 加上類型提示

前面我們在使用

createServer以及resp物件的時候,看不到任何的語法提示,必須隨時跟著node官方文件去邊用邊查,有點不方便 但沒關係,我們可以使用ts.d.ts檔案來幫助我們提供語法提示功能,注意,我們不是使用ts進行開發,只是使用它的語法提示功能而已

    初始化項目--
  1. npm init -y
  2. #安裝
  3. @types/node# -- pnpm i @types/node -D
  4. 在專案目錄下建立
  5. jsconfig.json文件,將node_modules排除在外,沒必要對其進行檢查
  6. {  "compilerOptions": {
        "checkJs": true
      },  
      "exclude": ["node_modules", "**/node_modules/*"]
    }
不知道你有沒有發現上面的程式碼其實是有一個錯誤的呢?

checkJs能夠幫助我們檢查類型錯誤問題,可以根據需要選擇是否開啟 可以看到,開啟檢查後立刻就給我們提示了參數類型不符的問題

淺析用Node建立一個簡單的HTTP伺服器#

这时候将鼠标悬浮在listen方法上,就能够看到该方法的签名

淺析用Node建立一個簡單的HTTP伺服器

可以看到,原来port参数需要是number类型,但是我们定义的时候是string类型,所以没匹配上,将其修改为number8080即可 而且可以直接查看到相关api的文档,不需要打开node官方的文档找半天去查看了


4. 返回多个字符串的响应体

前面我们的简单http server中只返回了一句话,那么是否能够返回多句话呢? 这就要用到resp对象的write方法了,end只能够返回一次内容,而是用write方法,我们可以多次写入内容到响应体中,最后只用调用一次end,并且不传递任何参数,只让他完成发送响应体的功能

const { createServer } = require("http");
const HOST = "localhost";
const PORT = 8080;

const server = createServer((req, resp) => {
  resp.writeHead(200, { "Content-Type": "text/plain" });  
  console.log("server is working...");  
  
  // write some lorem sentences
  resp.write("Lorem ipsum dolor sit amet consectetur adipisicing elit.\n");
  resp.write("Omnis eligendi aperiam delectus?\n");
  resp.write("Aut, quam quo!\n");

  resp.end();
});

server.listen(PORT, HOST, (error) => {
  if (error) {    
  console.log("Something wrong: ", error);    
  return;
  }  
  console.log(`server is listening on http://${HOST}:${PORT} ...`);
});

这次我们写入了三句话,现在的效果就变成这样啦

淺析用Node建立一個簡單的HTTP伺服器


5. 返回html

我们不仅可以返回字符串给浏览器,还可以直接读取html文件的内容并将其作为结果返回给浏览器 这就需要用到另一个Node.js的内置模块 -- fs,该模块提供了文件操作的功能 使用fs.readFile可以异步进行读取文件的操作,但是它不会返回promise对象,因此我们需要传入回调去处理读取到文件后的操作 还可以使用fs.readFileSync进行同步阻塞读取文件,这里我们选择异步读取

const { createServer } = require("http");
const fs = require("fs");
const HOST = "localhost";

const PORT = 8080;const server = createServer((req, resp) => {
  // change the MIME type from text/plain to text/html
  resp.writeHead(200, { "Content-Type": "text/html" });  
  
  // read the html file content
  fs.readFile("index.html", (err, data) => { 
     if (err) {  
      console.error(      
        "an error occurred while reading the html file content: ",
        err
      );      throw err;
    }    
    console.log("operation success!");

    resp.write(data);
    resp.end();
  });
});

server.listen(PORT, HOST, (error) => {
  if (error) {    
  console.log("Something wrong: ", error);    
  return;
  }  
  console.log(`server is listening on http://${HOST}:${PORT} ...`);
});

现在的结果就像下面这样:

淺析用Node建立一個簡單的HTTP伺服器

成功将html返回注意:这里需要将响应头的**Content-Type**改为**text/html**,告知浏览器我们返回的是**html**文件的内容,如果仍然以**text/plain**返回的话,浏览器不会对返回的内容进行解析,即便它是符合**html**语法的也不会解析,就像下面这样:

淺析用Node建立一個簡單的HTTP伺服器


6. 返回JSON

当我们需要编写一个后端服务器,只负责返回接口数据的时候,就需要返回json格式的内容了,相信聪明的你也知道该怎么处理了:

  1. MIME类型设置为application/json
  2. resp.write的时候传入的是json字符串,可以使用JSON.stringify处理对象后返回
const { createServer } = require("http");
const HOST = "localhost";
const PORT = 8080;

const server = createServer((req, resp) => { 
 // change the MIME type to application/json
  resp.writeHead(200, { "Content-Type": "application/json" });  
  
  // create a json data by using an object  
  const jsonDataObj = {
      code: 0,    
      message: "success",    
      data: {  
          name: "plasticine",      
          age: 20,      
          hobby: "coding",
    },
  };

  resp.write(JSON.stringify(jsonDataObj));
  resp.end();
});

server.listen(PORT, HOST, (error) => {
  if (error) { 
     console.log("Something wrong: ", error);    
     return;
  }  
  console.log(`server is listening on http://${HOST}:${PORT} ...`);
});

结果如下:

淺析用Node建立一個簡單的HTTP伺服器


7. 返回pdf文件

和之前返回html文件的思路类似,都是一个设置响应头MIME类型,读取文件,返回文件内容的过程 但是这次我们搞点不一样的 我们的思路是在服务器运行的时候生成一个pdf文件,并将它返回 还需要将MIME的类型改为application/pdf生成pdf文件需要用到一个库 -- pdfkit

pnpm i pdfkit

首先我们编写一个创建pdf文件的函数,因为创建pdf文件还需要进行一些写入操作,不确定什么时候会完成,但是我们的请求必须等到pdf文件创建完成后才能得到响应 所以我们需要将它变成异步进行的,返回一个promise

/**
 * @description 创建 pdf 文件
 */const createPdf = () => {
   return new Promise((resolve, reject) => {
       if (!fs.existsSync("example.pdf")) {      
       // create a PDFDocument object      
       const doc = new PDFDocument();
       
       // create write stream by piping the pdf content.
       doc.pipe(fs.createWriteStream("example.pdf"));   
        
      // add some contents to pdf document
      doc.fontSize(16).text("Hello PDF", 100, 100);   
         
      // complete the operation of generating PDF file.
      doc.end();
    }

    resolve("success");
  });
};

这里使用到了管道操作,将PDFDocument对象的内容通过管道传到新创建的写入流中,当完成操作后我们就通过resovle告知外界已经创建好pdf文件了 然后在服务端代码中调用

const server = createServer(async (req, resp) => {
  // change the MIME type to application/pdf
  resp.writeHead(200, { "Content-Type": "application/pdf" });  
  
  // create pdf file  
  await createPdf();  
  
  // read created pdf file
  fs.readFile("example.pdf", (err, data) => {
      if (err) { 
       console.error(        
        "an error occurred while reading the pdf file content: ",
        err
      );      
      throw err;
    }    
    console.log("operation success!");

    resp.end(data);
  });
});

server.listen(PORT, HOST, (error) => {
  if (error) {
      console.log("Something wrong: ", error);    
      return;
  }  
  console.log(`server is listening on http://${HOST}:${PORT} ...`);
});

现在浏览器就可以读取到创建的pdf文件了

淺析用Node建立一個簡單的HTTP伺服器


8. 返回音频文件

思路依然是一样的,读取一个音频文件,然后通过管道将它送到resp对象中再返回即可

const { createServer } = require("http");
const { stat, createReadStream } = require("fs");
const HOST = "localhost";
const PORT = 8080;

const server = createServer((req, resp) => {
  // change the MIME type to audio/mpe
  resp.writeHead(200, { "Content-Type": "audio/mp3" });  
  const mp3FileName = "audio.mp3";

  stat(mp3FileName, (err, stats) => {
    if (stats.isFile()) {      
      const rs = createReadStream(mp3FileName);      
      
      // pipe the read stream to resp
      rs.pipe(resp);
    } else {
      resp.end("mp3 file not exists");
    }
  });
});

server.listen(PORT, HOST, (error) => {
  if (error) {    
  console.log("Something wrong: ", error);    
  return;
  }  
  console.log(`server is listening on http://${HOST}:${PORT} ...`);
});

效果如下

1淺析用Node建立一個簡單的HTTP伺服器

打开后就是一个播放音频的界面,这是chrome提供的对音频文件的展示,并且打开控制台会发现有返回音频文件

11-淺析用Node建立一個簡單的HTTP伺服器

注意:将音频文件流通过管道传到**resp**后,不需要调用**resp.end()**方法,因为这会关闭整个响应,导致音频文件无法获取

1淺析用Node建立一個簡單的HTTP伺服器

1淺析用Node建立一個簡單的HTTP伺服器


9. 返回视频文件

视频文件和音频文件的处理是一样的,只是MIME的类型要改成video/mp4,其他都一样

const { createServer } = require("http");
const { stat, createReadStream } = require("fs");
const HOST = "localhost";
const PORT = 8080;
const server = createServer((req, resp) => {  
// change the MIME type to audio/mpe
  resp.writeHead(200, { "Content-Type": "audio/mp4" });  
  const mp4FileName = "video.mp4";

  stat(mp4FileName, (err, stats) => { 
     if (stats.isFile()) {      
     const rs = createReadStream(mp4FileName);      
     // pipe the read stream to resp
      rs.pipe(resp);
    } else {
      resp.end("mp4 file not exists");
    }
  });
});

server.listen(PORT, HOST, (error) => { 
 if (error) {    
 console.log("Something wrong: ", error);    
 return;
  }  
  console.log(`server is listening on http://${HOST}:${PORT} ...`);
});

1淺析用Node建立一個簡單的HTTP伺服器


总结

我们学会了:

  • 如何使用Node创建一个http服务器
  • js加上类型提示
  • 如何返回字符串响应体
  • 如何返回html
  • 如何返回JSON
  • 如何生成并返回pdf文件
  • 如何返回音频文件
  • 如何返回视频文件

虽然内容简单,但还是希望你能跟着动手敲一敲,不要以为简单就看看就算了,看了不代表会了,真正动手实现过后才会找到自己的问题

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

以上是淺析用Node建立一個簡單的HTTP伺服器的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文轉載於:juejin.cn。如有侵權,請聯絡admin@php.cn刪除