摘要:中可以利用模塊進行服務器的搭建。每個響應都必須調(diào)用方法,并且在最后調(diào)用。中后面的部分叫做。方法封裝了和方法常識模塊的服務器默認返回的數(shù)據(jù)類型是模塊中的屬性包含所有的狀態(tài)碼及其描述信息
使用Node進行網(wǎng)絡開發(fā)
用戶在瀏覽器中輸入網(wǎng)址 --> 獲得網(wǎng)頁的過程經(jīng)歷了幾個步驟:
通過瀏覽器發(fā)送一個請求到服務器(期間經(jīng)歷的DNS解析、TCP3次握手連接)
服務器分析、處理用戶的請求,并生產(chǎn)請求的內(nèi)容,然后發(fā)送給瀏覽器
瀏覽器解析服務發(fā)送回的數(shù)據(jù),生產(chǎn)網(wǎng)頁
服務器在HTTP協(xié)議中的服務器指:監(jiān)聽客戶端的請求,并且根據(jù)請求的內(nèi)容進行相應處理,返回響應給客戶端。
Node中可以利用http模塊進行Web服務器的搭建。
http模塊http模塊不是Node的核心模塊,需要利用require()加載
使用http.createServer()方法創(chuàng)建一個http服務器,返回一個http服務器對象
利用服務器對象進行開發(fā)
接收的回調(diào)函數(shù)是監(jiān)聽到客戶端請求時的回調(diào)函數(shù)
server.listen()方法可以開啟Web服務,監(jiān)聽某臺主機的某個端口
參數(shù)是(port, hostname, backlog, callback)
port是監(jiān)聽主機的端口號;hostname是監(jiān)聽主機的IP地址;callback是服務器成功開啟后的回調(diào)函數(shù)(開啟服務器后,再連接數(shù)據(jù)庫)
// 搭建一個HTTP服務器,用于處理用戶發(fā)送的http請求 // http模塊不是核心模塊,需要require()導入 var http = require("http"); // http模塊的createServer()方法可以返回一個標準http服務器對象 // 通過服務器對象來進行開發(fā) // callback是監(jiān)聽到客戶端連接的回調(diào)函數(shù) var server = http.createServer(callback); // 服務器監(jiān)聽某個網(wǎng)卡上的某個端口,開啟服務 // listen(port, hostname, backlog, callback) // port是監(jiān)聽的端口,hostname是監(jiān)聽主機的ip地址,callback是服務器開啟成功后的回調(diào)函數(shù) // 服務器開啟失敗時觸發(fā)error事件 server.on("error", function (err) { console.log(err); }) // listening事件在服務器開啟成功時觸發(fā) server.on("listening", function () { console.log("listening...8080"); }) // 監(jiān)聽來自客戶端的請求事件,在接收到請求時觸發(fā) server.on("request", function () { console.log("there is a request"); }) server.listen(8080, "localhost");主要的事件
服務器開啟失敗的事件error的監(jiān)聽:server.on("errro", function(err) {})
服務器開啟成功的事件listening的監(jiān)聽:server.on("listening", function(err) {}),可以寫在server.listen()方法的回調(diào)函數(shù)中
服務器接收到請求的事件request的監(jiān)聽:server.on("request", function(err, req, res) {}),可以寫在http.createServer()方法的回調(diào)函數(shù)中
參數(shù)對象request事件接收兩個參數(shù):
request對象:提供客戶端請求相關數(shù)據(jù)的對象,是http.IncomingMessage類的一個實例,有對應的屬性與方法
httpVersion屬性:使用的HTTP協(xié)議版本
header屬性:請求頭中相關的數(shù)據(jù)
url屬性:
method屬性:請求的方式
...
response對象:服務端向客戶端發(fā)送的響應數(shù)據(jù)對象,是http.ServerResponse類的一個實例
write(chunk, [encoding]):發(fā)送一個數(shù)據(jù)庫到響應的正文(網(wǎng)頁的內(nèi)容數(shù)據(jù))中,需要在發(fā)送完成后調(diào)用res.end()方法
end(chunk, [encoding], [callback]):在通過write()方法發(fā)送完所有正文和頭信息后,需要res.end()告訴服務器數(shù)據(jù)全部發(fā)送完成。每個響應都必須調(diào)用res.end()方法,并且在最后調(diào)用。
如果指定了 chunk,則它等同于調(diào)用 response.write(chunk, encoding) 之后調(diào)用 response.end(callback)
writeHeader(statusCode [, statusMessage] [, headers]):寫入頭信息,在res.write()前調(diào)用,并且一次響應中只能調(diào)用一次,頭信息寫在一個對象中
statusCode屬性和setHeader()方法可以組合實現(xiàn)writeHeader()的功能
server.on("request", function (req, res) { console.log("there is a request"); var chunk = "url處理hello world
"; // Buffer.byteLength(chunk)以字節(jié)為單位,告訴瀏覽器以純文本解析傳回的數(shù)據(jù) res.writeHeader(200, "OK", {"Content-type": "text/plain", "Content-length": Buffer.byteLength(chunk)}); res.end(chunk, "utf-8"); })
根據(jù)用戶請求的path返回不同的數(shù)據(jù),使用req.url可以獲取path信息。
req.url中?后面的部分叫做query。
Node下的url模塊可以處理請求的中的req.url
使用switch結(jié)構(gòu),為不同的pathname劃分不同的邏輯處理方式
server.on("request", function (req, res) { console.log(req.url); // req.url獲取請求的路徑path信息 var urlStr = url.parse(req.url); switch(urlStr.pathname) { case "/": // 首頁 res.writeHeader(200, "OK", {"Content-type": "text/plain"}); res.end("使用fs模塊實現(xiàn)行為與表現(xiàn)分離首頁
", "utf-8"); break; case "/users": // 用戶頁 res.writeHeader(200, "OK", {"Content-type": "text/plain"}); res.end("用戶頁
", "utf-8"); break; default : // 不存在 res.writeHeader(404, "Not Found", {"Content-type": "text/plain"}); res.end("出錯
", "utf-8"); break; } })
根據(jù)用戶不同訪問的不同路徑,執(zhí)行不同操作,讀取不同頁面
server.on("request", function (req, res) { console.log(req.url); var urlStr = url.parse(req.url); switch(urlStr.pathname) { case "/": // 首頁 sendData(htmlDir + "/index.html", req, res); // 請求不同的路徑,讀取不同的頁面返回給客戶端 break; case "/users": // 用戶頁 sendData(htmlDir + "/user.html", req, res); break; default : // 不存在 sendData(htmlDir + "/404.html", req, res); break; } }); // 每次請求都讀取靜態(tài)頁面,再輸出。 fs.readFile()方法封裝了fs.open()、fs.read()和fs.close()方法 // fs.readFile()返回值是原始的buffer對象 function sendData(file, req, res) { fs.readFile(file, function (err, data) { if(err) { res.writeHeader(404, "Not Found", {"Content-Type": "text/html"}); res.end("Not Found"); } else { res.writeHeader(200, "OK", {"Content-Type": "text/html"}); res.end(data); } }); }處理GET與POST請求提交的數(shù)據(jù)
通過GET方法傳遞的數(shù)據(jù)可以使用url.parse(req.url).query獲取到GET請求提交的數(shù)據(jù),使用querystring內(nèi)置模塊(無需加載)來解析
GET請求提交的數(shù)據(jù)綁定在url中,使用querystring.parse()方法解析url的query屬性便可以得到GET請求提交的數(shù)據(jù)
POST請求提交的數(shù)據(jù)在HTTP的Body中,服務器接收到的是數(shù)據(jù)流(因為POST請求提交的數(shù)據(jù)量較大,需要從緩沖區(qū)區(qū)讀取chunk)
利用request對象的data事件,觸發(fā)回調(diào)函數(shù)接收所有提交的數(shù)據(jù)??梢詫⑵淦唇拥揭粋€字符串上
接收完所有數(shù)據(jù)后觸發(fā)end事件,此時才可以使用querystring.parse()解析接收到的所有數(shù)據(jù)
var http = require("http"); var url = require("url"); var fs = require("fs"); var querystring = require("querystring"); var server = http.createServer(); var htmlDir = __dirname + "/html/"; // 使用fs讀取html目錄下的文件 server.on("request", function (req, res) { var urlStr = url.parse(req.url); switch(urlStr.pathname) { case "/": // 首頁 sendData(htmlDir + "/index.html", req, res); break; case "/users": // 用戶頁 sendData(htmlDir + "/user.html", req, res); break; // 增加登錄頁面的路由 case "/login": // 用戶頁 sendData(htmlDir + "/login.html", req, res); break; // 增加登錄頁面提交數(shù)據(jù)的處理 case "/login/check": // 用戶頁 if(req.method.toUpperCase() === "GET") { console.log(querystring.parse(urlStr.query)); // 使用querystring.parse()將傳遞的數(shù)據(jù)解析為一個對象 } if(req.method.toUpperCase() === "POST") { var str = ""; // 用來接收POST傳遞來的數(shù)據(jù) req.on("data", function (chunk) { str += chunk; }) req.on("end", function () { console.log(querystring.parse(str)); }) } break; default : // 不存在 sendData(htmlDir + "/404.html", req, res); break; } }); // 每次請求都讀取靜態(tài)頁面,再輸出。 fs.readFile()方法封裝了fs.open()、fs.read()和fs.close()方法 function sendData(file, req, res) { fs.readFile(file, function (err, data) { if(err) { res.writeHeader(404, "Not Found", {"Content-Type": "text/html"}); res.end("Not Found"); } else { res.writeHeader(200, "OK", {"Content-Type": "text/html"}); res.end(data); } }); } server.listen(8080, "localhost");常識
http模塊的服務器默認返回的數(shù)據(jù)類型是text/html
http模塊中的http.STATUS_CODES屬性包含所有的狀態(tài)碼及其描述信息
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/86900.html
摘要:感謝大神的免費的計算機編程類中文書籍收錄并推薦地址,以后在倉庫里更新地址,聲音版全文狼叔如何正確的學習簡介現(xiàn)在,越來越多的科技公司和開發(fā)者開始使用開發(fā)各種應用。 說明 2017-12-14 我發(fā)了一篇文章《沒用過Node.js,就別瞎逼逼》是因為有人在知乎上黑Node.js。那篇文章的反響還是相當不錯的,甚至連著名的hax賀老都很認同,下班時讀那篇文章,竟然坐車的還坐過站了。大家可以很...
摘要:感謝大神的免費的計算機編程類中文書籍收錄并推薦地址,以后在倉庫里更新地址,聲音版全文狼叔如何正確的學習簡介現(xiàn)在,越來越多的科技公司和開發(fā)者開始使用開發(fā)各種應用。 說明 2017-12-14 我發(fā)了一篇文章《沒用過Node.js,就別瞎逼逼》是因為有人在知乎上黑Node.js。那篇文章的反響還是相當不錯的,甚至連著名的hax賀老都很認同,下班時讀那篇文章,竟然坐車的還坐過站了。大家可以很...
摘要:的網(wǎng)站仍然使用有漏洞庫上周發(fā)布了開源社區(qū)安全現(xiàn)狀報告,發(fā)現(xiàn)隨著開源社區(qū)的日漸活躍,開源代碼中包含的安全漏洞以及影響的范圍也在不斷擴大。與應用安全是流行的服務端框架,本文即是介紹如何使用以及其他的框架來增強應用的安全性。 showImg(https://segmentfault.com/img/remote/1460000012181337?w=1240&h=826); 前端每周清單專注...
摘要:從社區(qū)和過往的經(jīng)驗而言異步編程的難題已經(jīng)基本解決無論是通過事件還是通過模式或者流程控制庫。本章主要介紹了主流的幾種異步編程解決方案這是目前中主要使用的方案。最后因為人們總是習慣性地以線性的方式進行思考以致異步編程相對較為難以掌握。 前言 如果你想要深入學習Node,那你不能錯過《深入淺出Node.js》這本書,它從不同的視角介紹了 Node 內(nèi)在的特點和結(jié)構(gòu)。由首章Node 介紹為索引...
摘要:這些特性不僅帶來了大的性能提升,還減少多線程程序設計的復雜性,進而提高了開發(fā)效率。由公司建立的云計算平臺率先支持了。 前言 本文章主要寫給那些想了解node語言的開發(fā),我的目標希望大家通過閱讀本篇文章能夠簡單使用node進行開發(fā),以及了解一些事件驅(qū)動的異步編程風格,主要分node的背景,安裝配置,模塊創(chuàng)建引用等幾個方面描述 建議大家在閱讀本篇文章途中 可以親自嘗試一下我所帶來的小例子,...
閱讀 4018·2021-10-09 09:43
閱讀 2901·2021-10-08 10:05
閱讀 2774·2021-09-08 10:44
閱讀 905·2019-08-30 15:52
閱讀 2852·2019-08-26 17:01
閱讀 3046·2019-08-26 13:54
閱讀 1681·2019-08-26 10:48
閱讀 833·2019-08-23 14:41