NodeJS-API


NodeJS是C語言開發的V8引擎,代碼格式是JS寫法的,做了服務器語言的一門編程語言
NodeJS更新速度非常的快,所以很多的API更改刪除很快,所以要保證版本一致,框架也是,插件也是,不符合版本運行起來就會報錯,說找不到這個方法什么的

我們知道瀏覽器JS分為Dom+Bom+ES56789,而NodeJS明顯沒有Dom,Bom是運行環境帶來的方法,Bom在瀏覽器是window對象,cookie,瀏覽歷史等等,而NodeJS就沒有這些了,他的Bom是下載node的時候帶來的,也就是官網文檔顯示的那些,ES則是跟瀏覽器一樣的,所以需要先會ES作為前提,ES學習可以查看JS分類

下面的筆記來自
NodeJS官方文檔,v12
掘金大佬的總結

具體的常用的知識點有

  • global全局
  • buffer二進制
  • console控制台
  • crypto加密
  • events事件
  • module模塊
  • http
  • path
  • fs文件
  • 計時器
  • url
  • zlib壓縮
  • querystring

global全局
這個就是瀏覽器的window,在nodejs里是沒有window變量的

看過nodejs代碼的人應該知道,nodejs跟java一樣,有很多內置的方法是需要引入模塊的,比如你要操作文件,不是直接調用fs的方法,需要先引入內置的fs模塊才行,java也是,就算是生成一個數組也需要引入系統內置的Array-jar包,而全局變量就是指不需要引入模塊的就能使用的,
上面的buffer,console,module,計時器,當前運行路徑,process就不需要引入模塊

module模塊
模塊最怕的就是相互引用

記得ES6的模塊化嗎

// 暴露多個
export var firstName = 'Michael';
export var lastName = 'Jackson';

// 只能暴露一個
export default function () {
  console.log('foo');
}

// 引入
import { firstName, lastName, year } from './profile.js';

nodejs模塊

// 暴露多個
exports.age = '123';
exports.name = "abc";

// 暴露一個
// 沒有

// 引入
// 這個a一定是個對象,不能跟es6模塊化一樣實現解構賦值
const a = require('./a.js');

路徑
不要使用相對路徑,因為nodejs運行的時候,相對路徑是相對於工作路徑,比如a.js旁邊就有個img文件夾里面有個圖片,直接執行a.js就可以用相對路徑去拿到這個圖片,但是如果是a.js被別的文件夾引入后執行的,那他的相對路徑就找不到img文件夾了

console.log('__dirname:', __dirname); // 當前所在絕對路徑文件夾
console.log('__filename:', __filename); // 當前所在絕對路徑文件

// 這個是path模塊的方法
// 如果不希望自己手動處理 / 的問題,使用 path.join
path.join(__dirname, 'view.html');
path.join(__dirname, 'views', 'view.html');

process
進程,當前主進程,有個env全局變量了解一下

process.env.NODE_ENV = 'development';
console.log(process.env.NODE_ENV);

// 防止起高樓,樓塌了
// 在原生node中有一個 process.on方法,可以守護你的進程即使報錯也不崩潰:
process.on('uncaughtException',(err)=>{
    console.error(err)
})

buffer
用來轉碼的還有什么二進制轉六進制什么的,重要的是可以把base64轉文件

// 引入fs模塊
const fs = require('fs');
const uri = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgA...';
const base64Data = uri.split(',')[1];
const buf = Buffer(base64Data, 'base64');
fs.writeFileSync(`${__dirname}/secondmonkey.png`, buf);

計時器和console
這兩個跟瀏覽器一樣的用法

crypto加密
內置有很多的出名的加密方式比如MD5SHA256,但是不能解密,常用在連接微信服務器的時候生成簽名

const crypto = require('crypto');
const hash = crypto.createHash('md5');

// 可任意多次調用update():
hash.update('Hello, world!');
hash.update('Hello, nodejs!');
console.log(hash.digest('hex')); // 7e1977739...

const secret = 'abcdefg';
const hash = crypto.createHmac('sha256', secret).update('I love cupcakes').digest('hex');
console.log(hash.digest('hex'));   //   c0fa131bd7...

events事件
這是一個訂閱發布的模式,用一個數組存起來效果也一樣,很少用到,封裝插件和框架用的

const EventEmitter = require('events').EventEmitter;

class MusicPlayer extends EventEmitter {
  constructor() {
    super();
    this.playing = false; 
  }
}

const musicPlayer = new MusicPlayer();
musicPlayer.on('play', function (track) {
  this.playing = true;
});
musicPlayer.on('stop', function () {
  this.playing = false;
});

musicPlayer.emit('play', 'The Roots - The Fire');
setTimeout(function () {
  musicPlayer.emit('stop');
}, 1000);

fs只記住他能轉換文件格式編碼,判斷文件是否存在,文件監聽【vue的熱更新原理】,把文件讀取的功能都放在stream學習

fs
這個模塊的方法很多,常用的只要記住他可以判斷文件是否存在,對文件進行監聽【熱更新原理】,文件轉格式【base64上傳】,文件讀取,文件讀寫有兩個系列的API,一個是read_write,是讀取文件內部的文字代碼什么的【babel編譯】,一個是stream,是文件的整體傳輸

const fs = require('fs');

// 判斷文件是否存在,原來的fs.exists已經廢棄了
fs.stat("./txtDir", function(err, stats) {
    console.log(stats.isDirectory());
    console.log(stats);
});

// 文件監聽,fs.watchFile 比 fs.watch 低效,但更好用
fs.watch('./watchdir', console.log); // 穩定且快
fs.watchFile('./watchdir', console.log); // 跨平台

// 文件轉格式和read_write
// 生成 data URI
const fs = require('fs');
const mime = 'image/png';
const encoding = 'base64';
const base64Data = fs.readFileSync(`${__dirname}/monkey.png`).toString(encoding);
const uri = `data:${mime};${encoding},${base64Data}`;
console.log(uri);
// data URI 轉文件
const fs = require('fs');
const uri = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgA...';
const base64Data = uri.split(',')[1];
const buf = Buffer(base64Data, 'base64');
fs.writeFileSync(`${__dirname}/secondmonkey.png`, buf);

// stream和pipe
// 文件管道
const r = fs.createReadStream('file.txt');
const w = fs.createWriteStream('new.txt');
r.pipe(w);

// http管道
const http = require('http');
http.createServer((req, res) => {
  // 讀取文件后傳給瀏覽器
  fs.createReadStream(`${__dirname}/index.html`).pipe(res);
}).listen(8000);

// 壓縮,不經過z管道只能算是改名字
const zlib = require('zlib');
const r = fs.createReadStream('file.txt');
const z = zlib.createGzip();
const w = fs.createWriteStream('file.txt.gz');
r.pipe(z).pipe(w);

path
用來解析路徑和拼接路徑的
為什么需要
一,路徑的加減法計算自己很難做,就像上面說的工作路徑__dirname計算一樣
二,不同虛擬機的路徑表示是不一樣的,在linux是雙斜桿,在別的地方可能是冒號,反斜杠,為了能在別的系統上運行,用內置的方法拼接是最穩妥的

const path = require('path');

path.join('/foo', 'bar', 'baz/asdf', 'quux', '..');
// 返回: '/foo/bar/baz/asdf'

path.resolve('/foo/bar', './baz');
// 返回: '/foo/bar/baz'

path.parse('C:\\path\\dir\\file.txt');
// 返回:
// { root: 'C:\\',
//   dir: 'C:\\path\\dir',
//   base: 'file.txt',
//   ext: '.txt',
//   name: 'file' }

http 和 url 和 querystring
http模塊是nodejs最核心的模塊,也是他作為服務器語言的原因
url模塊是處理訪問路徑的
querystring模塊是處理請求體的數據的

const http = require("http");
const url  = require("url");
const querystring  = require("querystring");

// createServer 核心模塊的核心方法,回調函數有兩個參數
// 第一個參數request,表示請求,所有請求的相關數據都在里面
// 第二個參數是response,表示響應,通過調用它的內部方法向前端發送數據
http.createServer((request, response) => {
    // 當前服務器訪問的方式
    console.log(request.method); 

    // 把reques.url轉換為一個URL對象,第二個參數true一定要
    let myUrl = url.parse(request.url, true); 
    // 把reques.url轉換為一個URL對象,並且將query,search等屬性轉換為對象
    console.log("url對象:", myUrl);
    // 獲取myUrl 的hash部分(在vue和react中有的是用hash)  #test
    console.log("hash:"+myUrl.hash);
    // 獲取myUrl中包括端口的域名部分 http://www.test.com:80 
    console.log("host:"+myUrl.host);    
    // 獲取myUrl中的域名部分  http://www.test.com     
    console.log("hostname:"+myUrl.hostname); 
    // 獲取路徑部分 /a/b?id=10
    console.log("path:"+myUrl.path);    
    // 獲取myUrl端口 80 8080     
    console.log("port:"+myUrl.port);         
    // 獲取請求的參數 ?id=10
    console.log("search:"+myUrl.search);
    // 獲取接口路徑 /a/b  
    console.log("pathname:" +myURL.pathname);
    // 獲取請求的參數,整理格式,這個就是get請求的參數
    console.log("query:"+myUrl.query); 
    
    // 通過判斷路徑,做接口
    if(myURL.pathname=="/get"){
       // 獲取參數myUrl.query,然后去數據庫數據什么的...
       let myUrl = url.parse(request.url, true); 
       console.log(myUrl)
       // 設置響應頭部信息及編碼
       response.writeHead(200, {"Content-Type": "text/plain;charset=UTF-8"});
       // 返回
       response.write("成功");
       response.end('Responses');
    }else if(myURL.pathname=="/post"){
        // get請求的參數很好獲得,但是post就不一樣了
        var body = "";
        req.on('data', function (chunk) {
             body += chunk;
        });
        req.on('end', function () {
        // 解析參數
        body = url.parse(body);
        console.log(body)
        // 設置響應頭部信息及編碼
        response.writeHead(200, {'Content-Type': 'text/plain; charset=utf8'});
        // 返回
        response.write("成功");
        response.end('Responses');
    }else{
        response.writeHead(200, {'Content-Type': 'text/html; charset=utf8'});
        response.end('<h1>404 Not Found!</h1>')  
    }
   
}).listen(3000);

dgram數據報
就是socket通信,插件封裝好了,就用插件就行

其他
難道我大nodejs就這么點東西?
上面都是最基礎,最實用的模塊和代碼,每一個都能深挖出很多的東西
高端的還有子進程,多線程
框架選擇,數據庫連接,分布式,集群什么鬼的后續慢慢寫

為什么需要使用框架
按照上面的http示例代碼無限的if-else下去是可以做一個原生的服務器的,但是最后會又臭又長,所有就需要分成一個個請求出來寫,並且我們每次返回都需要去設定響應頭格式什么的,判斷非常的復雜,后來就演變出來很多的框架,比如express和koa,下一篇koa

NodeJS 和 Java的區別

查看【Linux/IO】筆記


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM