zoukankan      html  css  js  c++  java
  • 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】笔记

  • 相关阅读:
    学习WindowsPhone 2013/12/22
    spring-aop学习
    easymock+junit+spring学习·
    javaWeb实现文件上传与下载 (转)
    Java实现视频网站的视频上传、视频转码、视频关键帧抽图, 及视频播放功能
    jsp自定义标签
    listener监听器
    移植一个项目到本地的问题
    struts1拦截器
    eclipse开发 javafx(转)
  • 原文地址:https://www.cnblogs.com/pengdt/p/12072506.html
Copyright © 2011-2022 走看看