您好,登錄后才能下訂單哦!
這篇文章主要介紹“怎么用Node創(chuàng)建一個簡單的HTTP服務(wù)器”的相關(guān)知識,小編通過實際案例向大家展示操作過程,操作方法簡單快捷,實用性強,希望這篇“怎么用Node創(chuàng)建一個簡單的HTTP服務(wù)器”文章能幫助大家解決問題。
node.js
基于Chrome
的v8
引擎運行js
代碼,因此我們可以擺脫瀏覽器環(huán)境,直接在控制臺中運行js
代碼,比如下面這個hello world
代碼
console.log('hello world');
控制臺中直接使用node
即可運行
node.js
的內(nèi)置模塊http
提供了基本的http
服務(wù)的能力,基于CommonJS
規(guī)范,我們可以使用require
導(dǎo)入http
模塊進行使用http
模塊中有一個createServer
函數(shù)能夠讓我們創(chuàng)建一個http
服務(wù)器
其接收一個回調(diào)函數(shù)作為參數(shù),這個回調(diào)函數(shù)接收兩個參數(shù) -- request
和response
。
request
包括所有客戶端請求的信息,比如url
、請求頭header
、請求方式和請求體等
response
主要用于返回信息給客戶端,封裝了一些操作響應(yīng)體相關(guān)的操作,比如response.writeHead
方法就可以讓我們自定義返回體的頭部信息和狀態(tài)碼
當(dāng)我們將響應(yīng)體處理好了之后,調(diào)用response.end()
方法就可以將響應(yīng)體發(fā)送給客戶端
使用createServer
函數(shù)只是幫我們創(chuàng)建了一個Server
對象,并沒有讓其開啟監(jiān)聽,我們還需要調(diào)用server
對象的listen
方法才可以進行監(jiān)聽,真正作為一個服務(wù)器開始運行
listen
方法的第一個參數(shù)是監(jiān)聽的端口號,第二個參數(shù)則是綁定的主機ip
,第三個參數(shù)是一個回調(diào)函數(shù),會被http
模塊異步調(diào)用,當(dāng)遇到錯誤的時候,就能夠在這個回調(diào)函數(shù)的第一個參數(shù)中獲取到拋出的異常 ,我們可以選擇對異常進行處理,讓我們的服務(wù)器更加健壯
下面是使用http
模塊創(chuàng)建一個簡單服務(wù)器的例子
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
運行它,創(chuàng)造一個屬于你的服務(wù)器!服務(wù)器運行后,瀏覽器訪問http://localhost:8080即可訪問到這個服務(wù)器
也可以使用nodemon
運行它,這樣當(dāng)我們的代碼發(fā)生變化的時候就不需要手動終止程序再重新運行了
npm i -g nodemon
建議全局安裝它,這樣就可以直接使用,不需要通過npx nodemon
去使用
使用也很簡單,直接將node
命令改成nodemon
命令即可
nodemon http-server.js
前面我們在使用createServer
以及resp
對象的時候,看不到任何的語法提示,必須隨時跟著node
官方文檔去邊用邊查,有點不方便
但是沒關(guān)系,我們可以使用ts
的.d.ts
文件幫助我們提供語法提示功能,注意,我們不是使用ts
進行開發(fā),只是使用它的語法提示功能而已
初始化項目 -- npm init -y
安裝@types/node
-- pnpm i @types/node -D
在項目目錄下創(chuàng)建jsconfig.json
文件,將node_modules
排除在外,沒必要對其進行檢查
{ "compilerOptions": {
"checkJs": true
},
"exclude": ["node_modules", "**/node_modules/*"]
}
不知道你是否有發(fā)現(xiàn)上面的代碼其實是有一處錯誤的呢?checkJs
能夠幫助我們檢查類型錯誤問題,可以根據(jù)需要選擇是否開啟
可以看到,開啟檢查后立馬就給我們提示了參數(shù)類型不匹配的問題
這時候?qū)⑹髽?biāo)懸浮在listen
方法上,就能夠看到該方法的簽名
可以看到,原來port
參數(shù)需要是number
類型,但是我們定義的時候是string
類型,所以沒匹配上,將其修改為number
的8080
即可
而且可以直接查看到相關(guān)api
的文檔,不需要打開node
官方的文檔找半天去查看了
前面我們的簡單http server
中只返回了一句話,那么是否能夠返回多句話呢?
這就要用到resp
對象的write
方法了,end
只能夠返回一次內(nèi)容,而是用write
方法,我們可以多次寫入內(nèi)容到響應(yīng)體中,最后只用調(diào)用一次end
,并且不傳遞任何參數(shù),只讓他完成發(fā)送響應(yīng)體的功能
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} ...`);
});
這次我們寫入了三句話,現(xiàn)在的效果就變成這樣啦
我們不僅可以返回字符串給瀏覽器,還可以直接讀取html
文件的內(nèi)容并將其作為結(jié)果返回給瀏覽器
這就需要用到另一個Node.js
的內(nèi)置模塊 -- fs
,該模塊提供了文件操作的功能
使用fs.readFile
可以異步進行讀取文件的操作,但是它不會返回promise
對象,因此我們需要傳入回調(diào)去處理讀取到文件后的操作
還可以使用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} ...`);
});
現(xiàn)在的結(jié)果就像下面這樣:
成功將html
返回注意:這里需要將響應(yīng)頭的**Content-Type**
改為**text/html**
,告知瀏覽器我們返回的是**html**
文件的內(nèi)容,如果仍然以**text/plain**
返回的話,瀏覽器不會對返回的內(nèi)容進行解析,即便它是符合**html**
語法的也不會解析,就像下面這樣:
當(dāng)我們需要編寫一個后端服務(wù)器,只負責(zé)返回接口數(shù)據(jù)的時候,就需要返回json
格式的內(nèi)容了,相信聰明的你也知道該怎么處理了:
將MIME
類型設(shè)置為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} ...`);
});
結(jié)果如下:
和之前返回html
文件的思路類似,都是一個設(shè)置響應(yīng)頭MIME
類型,讀取文件,返回文件內(nèi)容的過程
但是這次我們搞點不一樣的
我們的思路是在服務(wù)器運行的時候生成一個pdf
文件,并將它返回
還需要將MIME
的類型改為application/pdf
生成pdf
文件需要用到一個庫 -- pdfkit
pnpm i pdfkit
首先我們編寫一個創(chuàng)建pdf
文件的函數(shù),因為創(chuàng)建pdf
文件還需要進行一些寫入操作,不確定什么時候會完成,但是我們的請求必須等到pdf
文件創(chuàng)建完成后才能得到響應(yīng)
所以我們需要將它變成異步進行的,返回一個promise
/**
* @description 創(chuàng)建 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
對象的內(nèi)容通過管道傳到新創(chuàng)建的寫入流中,當(dāng)完成操作后我們就通過resovle
告知外界已經(jīng)創(chuàng)建好pdf
文件了
然后在服務(wù)端代碼中調(diào)用
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} ...`);
});
現(xiàn)在瀏覽器就可以讀取到創(chuàng)建的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
提供的對音頻文件的展示,并且打開控制臺會發(fā)現(xiàn)有返回音頻文件
注意:將音頻文件流通過管道傳到**resp**
后,不需要調(diào)用**resp.end()**
方法,因為這會關(guān)閉整個響應(yīng),導(dǎo)致音頻文件無法獲取
視頻文件和音頻文件的處理是一樣的,只是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} ...`);
});
關(guān)于“怎么用Node創(chuàng)建一個簡單的HTTP服務(wù)器”的內(nèi)容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業(yè)相關(guān)的知識,可以關(guān)注億速云行業(yè)資訊頻道,小編每天都會為大家更新不同的知識點。
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。