淺析node.js
大家好,今天來給大家討論node.js這個東西,說起這個東西啊,可能大家已經很熟悉了,因為現在市場上運用的越來越廣泛,畢竟它的優點還是有目共睹的!
那麽,什麽是node.js呢?官方給出了這樣的定義:“node.js是一個基於Chrome V8引擎的JavaScript運行環境。Node.js使用了一個事件驅動、非阻塞式I/O的模型,使其輕量又高效“。這樣我們就能知道node.js是一個運行環境,而且具有輕量又高效的特點。
既然提到了運行環境,那麽我們都知道瀏覽器也是一個運行環境,他們之間有沒有區別呢?自然是有的,在瀏覽器安全環境下有一些安全性的限制,不允許調用底層的方法,但node環境允許調用底層的各種api,而且在node環境下我們是可以操作文件系統的(這個可厲害了!試想一下,如果瀏覽器能夠使用文件系統,那麽當你訪問一個惡意網站時)!
一般來說,node適合開發高並發的項目,一般在大型項目中作為中間層使用,搭node中間層的目的是解決高並發,同時解決性能問題,但是node本身也存在一些缺點:node處理大量計算時速度會比較慢!
要想學好node,就一定要熟練使用npm,npm是一個node的包管理倉庫,是世界上最大的開放源代碼的生態系統,也是一個網站,也是一條命令
這裏介紹一些node的使用方法,當然了,大家需要先安裝一下node,具體安裝方法可以百度上來看,很多,也很簡單!在此之前,我們要先說一下node中的模塊問題,node有很多自己的模塊,因為node遵循的是commonjs的規範,因此我們要使用內置模塊時直接通過require引用就好了,比如我們使用http模塊創建一個服務器
const http = require("http") const server = http.createServer(req,res()=>{ res.end("hello world") }) res.listen("9000")
除了內置模塊。npm上還有很多第三方模塊,我們可以通過下載來使用這些模塊,可以通過npm install 模塊名 --global(可以簡寫為-g)來進行全局下載,npm install 模塊 --save(-s)安裝項目依賴
好了,說完模塊問題,我們就可以來進行正式的npm命令使用了,首先我們應該去官網註冊有個npm賬號,當我們寫了一個不錯的模塊時,想要把該模塊上傳到npm網站時我們就可以這樣操作
//首先在cmd中進去我們的項目文件夾 c/d/e/://進入什麽盤(c還是d還是e) cd file//進去你的模塊文件夾 npm init //執行完這行命令後,會生成一個package.json的文件夾,文件夾中的name名要唯一,當這個文件夾存在時node就是一個包了 npm adduser 輸入賬號密碼 npm publish 上傳模塊 然後別人就可以通過npm install 模塊名來下載你的模塊了!
因為npm是國外的網站,可能有時候我們下載需要的資源時網速會有點那麽不盡人意,這個時候我們就需要用到nrm這個模塊了
npm install nrm -g//全局安裝 nrm ls //查看可以使用的源 nrm test 源名 //測試單個源的速度 nrm use 源名 //切換到你要使用的源 //這樣我們就可以把源切換到下載速度較快的源,就會加快好多了
關於yarn:
yarn類似於npm的替代品,與npm相差無幾,但是相比npm有以下幾個優點:
1>.yarn是異步的所以比npm快
2>.團隊編程中使用yarn,可以保證版本號一致,開發時不出錯
3>.本地的包會有緩存,安裝本本地存在的包時會非常快
值得註意的是用yarn下載模塊的時候是通過yarn add 模塊名 來下載的,而且不需要加-s。直接代表npm install 模塊名 --save
接下來我們來介紹一下node中常用的幾個模塊:
1.url模塊:
url.parse(urlString[, parseQueryString[, slashesDenoteHost]])
url.format(urlObject)
url.resolve(from, to)
代碼使用如下
const url=require("url"); //url.parse()解析url,返回值是URLobject; Const result=url.parse("https://www.baidu.com/s?ie=utf-8&f=8&rsv_bp=1&rsv_idx=1&tn=baidu&wd=node&oq=node&rsv_pq=aea4b4650005e274&rsv_t=b6efVwyWo9RLoHnJougYq4rPh%2B83TZcEX%2BdoFLqN8zcpvB2fgErBjdboWPo&rqlang=cn&rsv_enter=0",true); //urlformat.根據URLobject生成URL const rs=url.format(result); console.log(rs); //生成相對路徑或絕對路徑的一種方法 console.log(url.resolve("http://www.baidu.com/a/b/c","d")); //網址是/a/b/c //<a href="/d">跳轉到d</a> // 結果是http://www.baidu.com/a/b/d console.log(url.resolve("http://www.baudu.com/a/b/c","/d")); //網頁地址是/a/b/c // <a href="/d">跳轉到d</a> //結果是http://www.baidu.com/d
2、Query String
querystring.escape(str)對給定的字符串進行編碼
querystring.parse(str[, sep[, eq[, options]]])要解析的url
querystring.stringify(obj[, sep[, eq[, options]]])把對象轉換成jQuery對象
querystring.unescape(str)對給定的str解碼
Querystring.js代碼:
const querystring = require("querystring"); const str = "name%dell!age%28!gender%male"; //querystring.parse 對querys字符串進行解析,seprator=&,equal= const result = querystring.parse(str,"!","%"); //querystring.stringify 把對象轉化成query字符串 console.log(querystring.stringify(result, "!", "%")); const newStr = "a=1=2=3"; console.log(querystring.unescape(querystring.escape(newStr)));
3、HTTP模塊
HTTP小爬蟲 cheerio Request方法(擴展)
http.js代碼
const http = require("http");//引入http核心模塊 const cheerio = require(‘cheerio‘);//引入cheerio const fs = require("fs"); // //因為大多數請求都是get請求且不帶請求主體,所以node.js提供了更便捷方法,該方法與http.requirest()唯一區別就是它設置請求方式為get自定調用req.end(); http.get("http://www.easyvoa.com", (res) => {//http發送一個get請求 if(res.statusCode == 200) {//200頁面加載成功 let str = ""; res.setEncoding(‘utf8‘);//編碼避免出現亂碼 res.on("data", (data) => {//監聽data str += data; }) res.on("end", () => {//觸發end時間 const $ = cheerio.load(str);//用了一個第三方模塊,它的感覺像是jQuery實際上不是。只是幫助我們從一個字符串裏找出我們想要的字符串。 const titles = $(".title_a");把.title標簽裏面的內容存在titles let result = ""; for (var i = 0; i < titles.length; i++) { result += titles.eq(i).text() + ‘\n‘; } fs.writeFileSync("list.text", result); }) } })
4、event模塊
EventEmitter 事件的參數 只執行一個的事件監聽器
代碼如下:
const EventEmitter=require("events");//EventEmitter它大寫是因為events導出來的 是一個類,而類的首字母是大寫 class Wang extends EventEmitter{}// 自己定義了一個類繼承了EvenEtmitter{} const wang=new Wang();//創建一個wang實例對象 wang.on("change",()=>{//對象有一個on方法 console.log("change"); }) //wang.once("change",()=>{//once只執行一次 //console.log("haha"); //}) //wang.prependListener("change"); //wang.removeAlListener("change"); wang.emit("change");//emit觸發事件
5、fs模塊
得到文件與目錄的信息:stat
創建一個目錄:mkdir
創建文件並寫入內容:writeFile,appendFile
讀取文件的內容:readFileSyn
列出目錄的東西:readdir
重命名目錄或文件:rename
刪除目錄與文件:rmdir,unlink
代碼如下:
const fs=require("fs"); //得到文件與目錄的信息 // fs.stat("list.text",(err,stats)=>{ // console.log(stats.isDirectory()); // }) //創建一個目錄 // fs.mkdir("wang",(err)=>{ // if(err){ // console.log(error); // } // }) //創建文件並寫入內容 // fs.writeFile("lee.txt","content",(err)=>{ // console.log(err); // } fs.writeFileSync("lee1.txt","1111") fs.appendFileSync("lee1.txt","2222") console.log(123); // fs.readFile("lee1.txt",(err,data)=>{ // console.log(data); //}) //fs.readdir("./",()) //fs.readFile("lee1.txt",(err,data)=>{ // console.log(data);//<Buffer 31 31 31 31 32 32 32 32> //}) //列出目錄中的東西返回一個數組 //fs.readdir("./",(err,list)=>{ // console.log(list);//返回一個數組 //}) // fs.rename("lee.txt","llelele.txt",()=>{}) //重命名目錄或文件[‘ const read=fs.createReadStream("lee1.txt"); const write=fs.createWriteStream("leecopy.txt"); read.pipe(zlib.createGzip()).pipe(write); Server.js const server http.createServer((req,res)={ If(req.url!==”/favicon.ico”){ //Es6的解構賦值: const {pathname,query}=url.parse(req.url,true); (相當於: Pathname=url.parse(req.url,true).pathname; Query=url.parse(req.url,true).query; ) If(req.url==”/”){//如果訪問的是根目錄則返回index res.end(“index”); } if(req.url==”/list”){//如果訪問的是list則返回list res.end(“list”); }else{//否則返回404 res.end(“404”); } } console.log(req.url); Res.end(“hello world”); }) Server.listen(“3000”);
6、關於socket:網絡上的兩個程序通過一個雙向的通信連接實現數據的交換,這個連接的一端稱為一個socket。持久連接,全雙工,雙向通信;常用於:消息提示,聊天工具
代碼:
(1)服務器端:server.js //引入net模板,net中有socket const net=require("net"); /*每個用戶的連接,即保存所有用戶*/ const clients=[]; //創建服務 const server=net.createServer(); //監聽,當服務器被連接的時候,將連接用戶保存在clients數組中 server.on("connection",(client)=>{ //當一個用戶連接進來時,我給用戶一個id //將用戶存入所有用戶這個數組中 client.id=clients.length; clients.push(client); //設置編碼集合 client.setEncoding("utf8"); //監聽用戶是否給服務器發了這個數據 //如果發送了數據,服務器要把數據轉發給其他所有用戶--->群聊,聊天室 client.on("data",(data)=>{ //將數據發送給其他所有用戶 for(var i=0;i<clients.length;i++){ //如果存在,發送數據 if(clients[i]){ //轉發其他用戶 clients[i].write(data); } } }) //監聽用戶是否退出群聊 client.on("close",(data)=>{ //如果退出,將對應id用戶移除 clients[client.id]=null; }) //監聽用戶連接是否失敗 client.on("error",(data)=>{ //如果失敗,將對應id用戶移除 clients[client.id]=null; }) }) server.listen("9000","127.0.0.1"); (2)客戶端:client.js //net中有socket const net=require("net"); const readline=require("readline"); //創建一個客戶端 const client=new net.Socket(); //創建一個和命令行連接的接口(讀和寫) const rl = readline.createInterface({ input: process.stdin, output: process.stdout }); //連接服務器 client.connect("9000","127.0.0.1"); //設置編碼集合(buffer數據) client.setEncoding("utf8"); //服務器傳來數據,這裏做監聽 client.on("data",(data)=>{ console.log(data); }) //寫一個數據,往服務器發送數據 client.write("w_juan"); //對命令行數的監聽 //監聽控制臺輸入的內容發送給服務器 rl.on("line",(input)=>{ if(input==="quit"){ //銷毀 rl.close(); client.destory(); }else{ client.write(input); } })
7、websocket:
代碼如下:
(1) 服務器端: const WebSocket = require(‘ws‘); const server = new WebSocket.Server({ port: 9000 }); const clients = []; server.on(‘connection‘, (client) => { //存儲用戶 client.id = clients.length; clients.push(client); client.on(‘message‘, (message) => { //一旦發送信息,將message傳過去 for (var i = 0; i < clients.length; i++) { clients[i] && clients[i].send(message); /*if(clients[i]){ //轉發其他用戶 clients[i].send(message); }*/ } }); client.on(‘error‘, () => { clients[client.id] = null; }); client.on(‘close‘, () => { clients[client.id] = null; }); }); (2)客戶端: <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>聊天室</title> </head> <body> <input type="text" id="input" /> <button id="button" onclick="handleClick()">提交</button> <div id="div1"></div> <script type="text/javascript"> var client = new WebSocket("ws://127.0.0.1:9000"); input = document.getElementById("input"); div1 = document.getElementById("div1"); function handleClick() { client.send(input.value); } client.onmessage = function(e) { div1.innerHTML=e.data; } </script> </body> </html>
好了,今天就先給大家寫這麽多吧,歡迎大家來交流!總之,node涵蓋了前端和後端的很多內容,要想學好node,我們要深入理解前後端進行轉換的思想,在學好js的基礎上,盡可能的理解後端的運作及思維!祝大家早日拿下nodejs!
淺析node.js