Node.js之HTTP服務(wù)端和客戶端實(shí)現(xiàn)方式
服務(wù)端
先來看一個(gè)簡單的web服務(wù)器的實(shí)現(xiàn):
const http = require('http')
const port = 3000
const server = http.createServer((req, res) => {
res.statusCode = 200
res.setHeader('Content-Type', 'text/plain')
res.end('你好世界\n')
})
server.listen(port, () => {
console.log(`服務(wù)器運(yùn)行在 http://localhost:${port}/`)
})首先我們引入http模塊,然后調(diào)用http的createServer方法,創(chuàng)建http服務(wù),這個(gè)方法的參數(shù)是一個(gè)回調(diào),回調(diào)函數(shù)有兩個(gè)參數(shù),第一個(gè)是請求,第二個(gè)是響應(yīng)。
我們可以通過請求參數(shù)req獲取客戶端的請求數(shù)據(jù),然后通過賦值響應(yīng)參數(shù)res,來返回我們的響應(yīng)數(shù)據(jù)。
我們可以對上邊的httpServer修改一下,用到request請求回調(diào)將請求數(shù)據(jù)處理之后并返回。
const httpServer = http.createServer((request, response) => {
let data = "";
request.on("data", (chunck) => {
data += chunck;
console.log("request data: " + data);
console.log("response: " + data);
response.statusCode = 200;
response.setHeader("Content-Type", "text/plain");
response.write(
JSON.stringify({
name: "test",
content: data,
})
);
response.end();
});
request.on("end", () => {
console.log("request end: " + data);
});
});上邊的代碼,我們綁定了request的data事件,用來做數(shù)據(jù)處理并返回,還綁定了end事件,做請求結(jié)束前的數(shù)據(jù)處理。
運(yùn)行控制臺(tái)圖:

我們可以將上邊的代碼稍作封裝,來實(shí)現(xiàn)路由的分發(fā)。
const http = require("http");
const url = require("url");
let thisRequest;
class Person {
getJames() {
// 獲取請求正文
console.log(thisRequest.method); // POST
let bodyRaw = "";
thisRequest.on("data", (chunk) => {
bodyRaw += chunk;
return JSON.stringify({
name: "james",
content: bodyRaw,
});
});
thisRequest.on("end", () => {
// do something....
// console.log(bodyRaw);
});
}
}
class Animals {
getDog() {
return "dog";
}
}
let routeTree = {
"Person/getJames": new Person().getJames,
"Animals/getDog": new Animals().getDog,
};
// 中劃線轉(zhuǎn)駝峰
function toHump(words) {
return words.replace(/\-(\w)/g, function (all, letter) {
return letter.toUpperCase();
});
}
// 首字母大寫
function UCWords(words) {
return words.slice(0, 1).toUpperCase() + words.slice(1).toLowerCase();
}
class httpServerObj {
createServerAndListen() {
let httpServer = http.createServer((req, res) => {
thisRequest = req;
let content = "";
// let requestUrl = "http://localhost:3000/person/get-james";
let requestUrl = req.url;
if (requestUrl === "/favicon.ico") {
return;
}
let pathname = url.parse(requestUrl).pathname.slice(1);
if (pathname) {
let pathnameSlices = pathname.split("/");
let className = UCWords(pathnameSlices[0]);
let actionName = "";
if (pathnameSlices[1]) {
actionName = toHump(pathnameSlices[1]);
}
let routeKey = className + "/" + actionName;
if (routeTree.hasOwnProperty(routeKey)) {
content = routeTree[routeKey]();
} else {
content = "404";
}
} else {
content = "hello word";
}
res.statusCode = 200;
res.setHeader("Content-Type", "text/plain");
res.write(content);
res.end();
});
httpServer.listen(3000, () => {
console.log("running in port: 3000");
});
}
}
obj = new httpServerObj().createServerAndListen();每次請求會(huì)附帶網(wǎng)站ico圖標(biāo)的請求,這段代碼是為了屏蔽node發(fā)起網(wǎng)站ico圖標(biāo)的請求。
if (requestUrl === "/favicon.ico") {
return;
}當(dāng)然,上邊所有的功能實(shí)現(xiàn)在同一個(gè)文件,實(shí)際情況。
業(yè)務(wù)類是單獨(dú)分離出來的。
客戶端
發(fā)起http請求,我們可以用axios包來實(shí)現(xiàn),這里不做多余贅述。除此之外,我們可以用http包來發(fā)起http請求:
簡單示例:
const http = require("http");
const options = {
hostname: "127.0.0.1",
port: 3000,
path: "/work",
method: "GET",
};
const req = http.request(options, (res) => {
console.log(res.statusCode);
res.on("data", (d) => {
process.stdout.write(d);
// console.log(data);
});
});
req.on("error", (err) => {
console.log(err);
});
req.end();首先我們根據(jù)需要選擇包,如果https請求就選https包。
然后調(diào)用request方法,第一個(gè)參數(shù)是請求方法、請求地址、請求端口等請求數(shù)據(jù)。第二個(gè)參數(shù)是返回?cái)?shù)據(jù)的回調(diào)。
最后調(diào)用end方法結(jié)束請求。
稍作封裝:
const http = require("http");
class httpPackageClientObj {
byPost() {
let postData = JSON.stringify({
content: "白日依山盡,黃河入海流",
});
let options = {
hostname: "localhost",
port: 3000,
path: "/person/get-james",
agent: false,
method: "POST",
headers: {
"Content-Type": "application/json",
"Content-Length": Buffer.byteLength(postData),
},
};
let req = http.request(options, (res) => {
console.log(res.statusCode);
res.on("data", (buf) => {
process.stdout.write(buf);
});
});
req.on("error", (err) => {
console.error(err);
});
req.write(postData);
req.end();
}
byGet() {
let options = {
hostname: "localhost",
port: 3000,
path: "/person/get-james",
agent: false,
};
let req = http.request(options, (res) => {
console.log(res.statusCode);
res.on("data", (chunk) => {
if (Buffer.isBuffer(chunk)) {
console.log(chunk.toString());
} else {
console.log(chunk);
}
});
});
req.on("error", (err) => {
console.error(err);
});
req.end();
}
}
let httpClient = new httpPackageClientObj();
httpClient.byGet();
httpClient.byPost();我們可以看到post請求,通過調(diào)用write方法進(jìn)行數(shù)據(jù)傳輸。
總結(jié)
以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
相關(guān)文章
Nodejs中怎么實(shí)現(xiàn)函數(shù)的串行執(zhí)行
今天小編就為大家分享一篇關(guān)于Nodejs中怎么實(shí)現(xiàn)函數(shù)的串行執(zhí)行,小編覺得內(nèi)容挺不錯(cuò)的,現(xiàn)在分享給大家,具有很好的參考價(jià)值,需要的朋友一起跟隨小編來看看吧2019-03-03
Node.js通過配置?strict-ssl=false解決npm安裝卡住問題
使用npm安裝依賴包是常見的任務(wù)之一,有時(shí)會(huì)遇到安裝卡住的問題,本文就來介紹一下通過配置?strict-ssl=false解決npm安裝卡住問題,感興趣的可以了解一下2024-12-12
Node.js完整安裝配置指南(包含國內(nèi)鏡像配置)
本文介紹Node.js的安裝配置過程,包括使用Chocolatey、官網(wǎng)下載、國內(nèi)鏡像下載等安裝方法,驗(yàn)證安裝,配置國內(nèi)鏡像源,環(huán)境變量配置,npm配置優(yōu)化,常用鏡像測速腳本,使用nrm管理鏡像源,及故障排查內(nèi)容,最后推薦了完整的配置命令和立即解決方案,感興趣的朋友跟隨小編一起看看吧2026-03-03
Linux Centos7.2下安裝nodejs&npm配置全局路徑的教程
今天小編就為大家分享一篇Linux Centos7.2下安裝nodejs&npm配置全局路徑的教程,具有很好的參考價(jià)值,希望對大家有所幫助。一起跟隨小編過來看看吧2018-05-05
在Node.js下運(yùn)用MQTT協(xié)議實(shí)現(xiàn)即時(shí)通訊及離線推送的方法
這篇文章主要介紹了在Node.js下運(yùn)用MQTT協(xié)議實(shí)現(xiàn)即時(shí)通訊及離線推送的方法,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2019-01-01
nodejs中轉(zhuǎn)換URL字符串與查詢字符串詳解
這篇文章主要介紹了nodejs中轉(zhuǎn)換URL字符串與查詢字符串詳解,需要的朋友可以參考下2014-11-11

