node.js - day01/day02

35 阅读8分钟

一、软件架构

1.1 C/S(Client客户端/Server服务器端)

  • 优点
    1. 用户体验感较好
    2. 运行稳定
    3. 对带宽的要求低
  • 缺点
    1. 占硬盘空间
    2. 更新过于麻烦 - 服务器端和客户端都要更新

1.2 B/S(Browser浏览器端/Server服务器端)

  • 优点
    1. 几乎不占硬盘
    2. 更新简单 - 只需要更新服务器端
    3. 对电脑配置要求不高
  • 缺点
    1. 用户体验感较差
    2. 对带宽的要求高

二、Node.js

不是JS,但是语法和JavaScript非常相似,做的功能绝对不是特效!做的事和服务器端其他语言是一致(和数据库进行交互,成为了一个前端到数据库的中间桥梁)

2.1 目的:

  1. 使用代码搭建一个服务器&文件系统(服务器文件可以放在任何位置,但是不在你的电脑里,你可以根据网址来访问到我的东西)
  2. Node.js如何沟通前端和数据库

2.2 Node.js安装

  1. node.js官网下载-安装
  2. 检查你安装成功没:打开cmd输入:node -v - 查看版本号,如果有版本号代表你已经安装成功!

2.3 Node.js如何运行:3种

  • 交互模式 - 临时测试:打开cmd输入:node回车,就可以开始敲你的"js"代码
  • 脚本/文件模式 - 正式开发中:先创建xx.js,里面书写自己的代码 -> 打开cmd输入:node 文件的绝对路径
  • 安装插件:前提是至少前面两个方式能够成功,才可以安装插件。vscode的插件是code runner:对着文件出右键,第一个选项就是code runner,或者 右上角有一个开始按钮

2.4 js和node的区别

  • 相同点:都可以使用一切的ECMAScript的东西包括一切的API都可以使用,在服务器端不存在任何浏览器,所以不必担心兼容问题
  • 不同点
    1. JavaScript:DOM+BOM - 做特效
    2. Node.js:有很多的模块

2.5 Node.js最大的特点

  • 快、非常快
  • 因为官方提供的东西少,甚至连数据库的操作API都没有提供的
  • 使用了chrome浏览器的v8引擎

三、模块(module)

每一个xx.js文件,都可以称之为是一个模块

3.1 模块化开发

如果以一个网站来说,我们可以按功能分为很多模块:商家模块、商品模块、促销模块、用户模块、产品模块....

3.2 分工合作

将每个模块交给对应的人,完成,最后再由【主模块】进行引入
  • 每一个模块都有一个操作,可以用于公开/暴露自己的成员:exports。Node.js自带的一个预定义变量,可以直接使用,是一个对象,放在此对象里面的东西,就是允许公开的东西

语法

exports.属性名=属性值;
module.exports={
    属性名:属性值,
    ...
}
console.log(exports);//{}
// 方法一
/* exports.size = function (r) {return Math.PI*r*r}//圆的面积
exports.per = function (r) {return Math.PI*r*2}//圆的周长 */
// 方法二
module.exports = {
    size : function(r){return Math.PI*r*r},
    per : function(r){return Math.PI*r*2}
}
  • 每一个模块(主模块)都有一个操作,可以用于导入/引入其他模块require。Node.js自带的一个预定义变量,可以直接使用,是一个函数,函数中需要书写出引入模块的路径 语法:var x=require("./文件名")
  • 语法
var fz1 = require('./06-分支模块1')
console.log(fz1);//{ size: [Function (anonymous)], per: [Function (anonymous)] }
console.log(fz1.size(2));//12.566370614359172
console.log(fz1.per(3));//18.84955592153876

3.3 exports和module.exports有什么区别

  • 语法,写法,用法不同
  • 都是用于公开暴露自己的成员的
  • 但是exports={},写法是错误的
  • 其实Node.js底层有一句话:exports=module.exports
  • 其实真正做公开功能的是module.exports
  • 如果你使用了exports={};其实是你创建了一个新的空对象,把module.exports覆盖了,所以不在具有公开的功能

四、模块的分类:

4.1 官方模块

不需要下载,在你安装node.js环境的时候就已经带上了,但是某的模块可以需要引入,某的模块可能不需要引入:
  • Global模块:不需要引入的,可以直接使用
    1. __filename - 获取当前文件完整的绝对路径
    2. __dirname - 获取当前文件的文件夹的绝对路径
    3. exports - 空对象,可以用于公开暴露自己的成员
    4. require - 函数,可以用于导入其他模块
    5. module - 指代当前模块本身,甚至包含着以上4个操作
    6. 定时器(周期性、一次性、瞬间定时器)
      // 周期性定时器
      setInterval(function(){
          console.log(1);
      },500)
      // 一次性定时器
      setTimeout(function(){
          console.log(2);
      },1200)
      // 瞬间定时器
      setImmediate(function(){
          console.log(3);
      })
      
    7. console
  • querystring模块:解析查询字符串,使其变成一个对象,可以获取到前端传到后端的消息
    1. 需要引入:var qs = require('querystring');
    2. 作用:解析url查询字符串部分的功能
    3. var obj=qs.parse("查询字符串");
    4. 想要获得前端传来的每一个部分:obj.键名;
    5. 如果前端传来的是一个完整的url网址,他就解析不了了!
    const qs = require('querystring')
    console.log(qs);
    // 解析字符串
    var str = 'name=dy&pwd=123123&vip=1&email=610147162@qq.com';
    var obj = qs.parse(str);
    console.log(obj);
    console.log(obj.name);//dy
    
  • url模块
    1. 需要引入:var url = require('url');
    2. 作用:提供了解析url各个部分的功能
    3. var objUrl=url.parse("网址",true);//支持第二参数,是一个布尔值,默认为false,一旦设置为true,自动使用querystring模块的parse方法去解析查询字符串部分
    4. 查询字符串:objUrl.query.键名; - 前端form表单提交传到后端的东西
    5. 路由/文件相对路径/请求地址:objUrl.pathname - 判断路由的不同,去读取不同的HTML发送给我们的用户看
    var url = require('url')
    // console.log(url);
    //假设,前端向后端传来的完整网址:
    var str="https://www.paoge.com:443/new/index.html?name=dy&pwd=123123&vip=1&email=610147162@qq.com";
    var obj = url.parse(str,true)//trun代表自动解析查询字符串,可传也可以不传,默认值为false
    console.log(obj.query.name);//name
    
  • Buffer模块:缓冲区,可以将数据变成一个16进制的数字
    var buf = Buffer.from([1,2,3,4,5])
    var buf1 = Buffer.from('hello你好')
    console.log(buf);//<Buffer 01 02 03 04 05>
    console.log(buf1);//<Buffer 68 65 6c 6c 6f e4 bd a0 e5 a5 bd>
    console.log(buf1.toString());//hello你好
    
  • fs模块
    1. 需要引入:var fs = require('fs');
    2. 读取文档:
    var fs = require('fs')
    // console.log(fs);
    // 读取文档 异步
    fs.readFile(__dirname+'/public/01.txt',function(err,buf){
        console.log(err);//null
        console.log(buf);//<Buffer e4 bb 8a e5 a4 a9 e6 98 9f e6 9c 9f e4 b8 89>
    })
    // 读取文档 同步
    /* var buf = fs.readFileSync(__dirname+'/public/01.txt')
    console.log(buf);////<Buffer e4 bb 8a e5 a4 a9 e6 98 9f e6 9c 9f e4 b8 89> */
    console.log('后续代码');
    
    1. 写入文档:
    var fs = require('fs')
    // console.log(fs);
    // 写入文档 异步
    fs.writeFile(__dirname+'/public/01.txt','写入的内容',function(){
        console.log('写入完毕后要做什么必须放在这里');
    })
    // 写入文档 同步
    /* fs.writeFileSync(__dirname+'/public/01.txt','写入的内容-同步')
    console.log('写入完毕'); */
    console.log('后续代码');
    
    1. 追加文档:
    var fs = require('fs')
    // console.log(fs);
    // 追加文档 异步
    fs.appendFile(__dirname+'/public/01.txt','追加的内容',function(){
        console.log('追加完毕后要做什么必须放在这里');
    })
    // 写入文档 同步
    /* fs.writeFileSync(__dirname+'/public/01.txt','写入的内容-同步')
    console.log('写入完毕'); */
    console.log('后续代码');
    
  • http模块:搭建服务器
    var http = require('http');
    var url = require('url');
    var fs = require('fs');
    // 创建服务器应用
    var app = http.createServer();
    // 为其绑定监听端口 http端口默认80
    app.listen(8008);
    // 为其绑定请求事件:http:请求-响应模式,必须要有一个请求,才有一个响应
    app.on('request',(req,res)=>{
        // req:request(请求)对象,它有一个属性叫做req.url,可以获取到前端传到后端的路由和请求消息,但是路由和请求消息是融为一体的,不方便我们获取某个部分,所有我们引入了url,进行进行解析,分开两个部分
        // console.log(req.url);//得到的是路由和请求消息/index.html?name=zs
        var obj = url.parse(req.url,true)
        // console.log(obj);
        // 保存路由
        var router = obj.pathname
        console.log(router);
        // 判断路由的不同读取不同的页面给用户看
        if (router == '/' || router == '/index.html') {
            fs.readFile('./public/index.html',(err,buf)=>{
                //res:response(响应)对象,他有一个方法:res.end(响应的内容) - 可以响应给前端想要的东西
                res.end(buf)
                console.log(1);
                console.log(err);
            })
        // match方法类似indexOf 但是支持正则 找不到返回null
        } else if (router.match(/html|css|js|json|ttf|woff|woff2|png|jpg/) !== null) {
            fs.readFile(`./public${router}`,(err,buf)=>{
                res.end(buf)
                console.log(2);
            })
        }
    })
    

4.2 第三方模块

  • npm工具:Node Package Manager:Node.js的模块/包管理器,专门用于管理第三方模块的。
  • 作用:下载、更新、删除、维护包之间的依赖关系
  • 打开网址:npm官网www.npmjs.com/
  • 搜索你需要用到的模块:尽量用带有完全符合标签的那个包,或者是 第一个包:(mongoose)
    1、打开cmd:检查npm是否安装成功:npm -v
    2、在你的项目之中,再打开cmd
    3、下载:npm i 包名
    4、更新:npm up 包名
    5、删除:npm un 包名

4.3 自定义模块

自己书写的xx.js:require("./模块名");

  • 文件模块:创建xx.js去公开需要公开的内容,主模块要引入,必须写为require("./模块名");
  • 目录模块:3种用法
    1. 比如创建m1的文件夹,在其中创建index.js的文件,去公开需要公开的内容,主模块要引入,必须写为require("./m1");
    2. 比如创建m2的文件夹,在其中创建xx.js的文件,,去公开需要公开的内容,主模块要引入,必须写为require("./m2"),必须再创建一个package.json的配置文件,写入:{"main":"xx.js"};
    3. 创建一个文件夹必须名为:node_modules,再在其中创建出m3文件夹,在其中创建index.js的文件,去公开需要公开的内容,主模块要引入,必须写为require("m3");