怎麼使用NodeJS建立HTTP伺服器?以下這篇文章跟大家介紹一下使用Node建立一個簡單的HTTP伺服器的方法,希望對大家有幫助!
node.js
基於Chrome
的v8
引擎運行js
程式碼,因此我們可以擺脫瀏覽器環境,直接在控制台中執行js
程式碼,例如下面這個hello world
程式碼
console.log('hello world');
控制台中直接使用node
即可運行
node.js的內建模組
http提供了基本的
http服務的能力,基於
CommonJS規範,我們可以使用
require導入
http模組來使用
http模組中有一個
createServer函數能夠讓我們建立一個
http伺服器
其接收一個回呼函數作為參數,這個回呼函數接收兩個參數--
request和
response
包括所有客戶端請求的訊息,例如
url、請求頭
header、請求方式和請求體等
主要用於傳回訊息給客戶端,封裝了一些操作響應體相關的操作,例如
response.writeHead方法就可以讓我們自訂返回體的頭部資訊和狀態碼
response.end()方法就可以將回應體傳送給客戶端
使用
createServer函數只是幫我們建立了一個
Server對象,並沒有讓其開啟監聽,我們還需要呼叫
server對象的
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即可存取到這個伺服器
nodemon運行它,這樣當我們的程式碼改變的時候就不需要手動終止程式再重新運行了
npm i -g nodemon建議全域安裝它,這樣就可以直接使用,不需要透過
npx nodemon去使用
使用也很簡單,直接將
node指令改成
nodemon指令即可
nodemon http-server.js
createServer以及
resp物件的時候,看不到任何的語法提示,必須隨時跟著
node官方文件去邊用邊查,有點不方便
但沒關係,我們可以使用
ts的
.d.ts檔案來幫助我們提供語法提示功能,注意,我們不是使用
ts進行開發,只是使用它的語法提示功能而已
# --
pnpm i @types/node -D
文件,將
node_modules排除在外,沒必要對其進行檢查
{ "compilerOptions": { "checkJs": true }, "exclude": ["node_modules", "**/node_modules/*"] }
checkJs能夠幫助我們檢查類型錯誤問題,可以根據需要選擇是否開啟
可以看到,開啟檢查後立刻就給我們提示了參數類型不匹配的問題
listen方法上,就能夠看到該方法的簽章
可以看到,原来port
参数需要是number
类型,但是我们定义的时候是string
类型,所以没匹配上,将其修改为number
的8080
即可
而且可以直接查看到相关api
的文档,不需要打开node
官方的文档找半天去查看了
前面我们的简单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} ...`); });
这次我们写入了三句话,现在的效果就变成这样啦
我们不仅可以返回字符串给浏览器,还可以直接读取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} ...`); });
现在的结果就像下面这样:
成功将html
返回注意:这里需要将响应头的**Content-Type**
改为**text/html**
,告知浏览器我们返回的是**html**
文件的内容,如果仍然以**text/plain**
返回的话,浏览器不会对返回的内容进行解析,即便它是符合**html**
语法的也不会解析,就像下面这样:
当我们需要编写一个后端服务器,只负责返回接口数据的时候,就需要返回json
格式的内容了,相信聪明的你也知道该怎么处理了:
MIME
类型设置为application/json
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} ...`); });
结果如下:
和之前返回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
文件了
思路依然是一样的,读取一个音频文件,然后通过管道将它送到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} ...`); });
效果如下
打开后就是一个播放音频的界面,这是chrome
提供的对音频文件的展示,并且打开控制台会发现有返回音频文件
注意:将音频文件流通过管道传到**resp**
后,不需要调用**resp.end()**
方法,因为这会关闭整个响应,导致音频文件无法获取
视频文件和音频文件的处理是一样的,只是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} ...`); });
我们学会了:
Node
创建一个http
服务器js
加上类型提示html
JSON
pdf
文件虽然内容简单,但还是希望你能跟着动手敲一敲,不要以为简单就看看就算了,看了不代表会了,真正动手实现过后才会找到自己的问题
更多node相关知识,请访问:nodejs 教程!
以上是聊聊怎麼使用Node.js建立一個簡單的HTTP伺服器的詳細內容。更多資訊請關注PHP中文網其他相關文章!