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】笔记

相关推荐