Node.js之HTTP服務(wù)端和客戶端實(shí)現(xiàn)方式
服務(wù)端
先來看一個簡單的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ù),這個方法的參數(shù)是一個回調(diào),回調(diào)函數(shù)有兩個參數(shù),第一個是請求,第二個是響應(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)行控制臺圖:
我們可以將上邊的代碼稍作封裝,來實(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();
每次請求會附帶網(wǎng)站ico圖標(biāo)的請求,這段代碼是為了屏蔽node發(fā)起網(wǎng)站ico圖標(biāo)的請求。
if (requestUrl === "/favicon.ico") { return; }
當(dāng)然,上邊所有的功能實(shí)現(xiàn)在同一個文件,實(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方法,第一個參數(shù)是請求方法、請求地址、請求端口等請求數(shù)據(jù)。第二個參數(shù)是返回數(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é)
以上為個人經(jīng)驗(yàn),希望能給大家一個參考,也希望大家多多支持腳本之家。
相關(guān)文章
詳解Node.js中path模塊的resolve()和join()方法的區(qū)別
這篇文章主要介紹了詳解Node.js中path模塊的resolve()和join()方法的區(qū)別,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2018-10-10用純Node.JS彈出Windows系統(tǒng)消息提示框?qū)嵗?MessageBox)
這篇文章主要介紹了用純Node.JS彈出Windows系統(tǒng)消息提示框?qū)嵗?MessageBox),非常具有實(shí)用價值,需要的朋友可以參考下2017-05-05windows 下安裝nodejs 環(huán)境變量設(shè)置
windows 下安裝nodejs 了,也安裝了npm, 但是有時候切不能直接用request(‘ws’)這一類的東西.我覺得是確實(shí)環(huán)境變量或其他設(shè)置有問題,能否給個完整的設(shè)置方案:2017-02-02Node.js數(shù)據(jù)流Stream之Duplex流和Transform流用法
這篇文章介紹了Node.js數(shù)據(jù)流Stream之Duplex流和Transform流的用法,文中通過示例代碼介紹的非常詳細(xì)。對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下2022-07-07Node.js 中 http 模塊的深度剖析與實(shí)戰(zhàn)應(yīng)用小結(jié)
本文詳細(xì)介紹了Node.js中的http模塊,從創(chuàng)建HTTP服務(wù)器、處理請求與響應(yīng),到獲取請求參數(shù),每個環(huán)節(jié)都通過代碼示例進(jìn)行解析,旨在幫助開發(fā)者熟練掌握http模塊,構(gòu)建高效的網(wǎng)絡(luò)應(yīng)用,感興趣的朋友一起看看吧2025-01-01npm報錯:無法將"npm"項識別為cmdlet、函數(shù)、腳本文件或可運(yùn)行程序的名稱
這篇文章主要給大家介紹了關(guān)于npm報錯:無法將"npm"項識別為cmdlet、函數(shù)、腳本文件或可運(yùn)行程序的名稱的相關(guān)資料,文中將解決的辦法介紹的非常詳細(xì),需要的朋友可以參考下2023-02-02PHP和NodeJs開發(fā)的應(yīng)用如何共用Session
這篇文章主要介紹了PHP和NodeJs開發(fā)的應(yīng)用如何共用Session的相關(guān)資料及思路,需要的朋友可以參考下2015-04-04nodejs+socket.io實(shí)現(xiàn)p2p消息實(shí)時發(fā)送的項目實(shí)踐
本文主要介紹了nodejs+socket.io實(shí)現(xiàn)p2p消息實(shí)時發(fā)送,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2022-06-06