慕课网 前端面试加分福音--node基础 笔记

本文档介绍了Node.js的基础知识及其在搭建服务器、处理HTTP请求中的应用,并通过实战案例展示了如何实现用户登录和注册功能。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

写在前面

  • Node.js
  • API部分 √
  • 前端部分 ×

课程期望

  1. 了解Node是什么以及应用场景
  2. Node的基础知识
  3. 了解Node的核心模块
  4. 了解数据通信过程
  5. 自己实现登录、注册等功能
  6. 前后台的工作流程

这是课程的零碎笔记,包括但不限于案例实现。

Node.js介绍

Node介绍

Node的优势

优势

  1. 性能高
  2. 便于前端入手

作用

  • 写webAPI
  • 中间层:服务器中负责IO读写的中间层服务器
    性能 异步IO 处理数据 安全性
  • 前端工程化的一些工具都是基于node(webpack、gulp)
Node的环境搭建和运行
  • 官网下载 node-v-xx.msi 安装包 安装
  • node -v 检测是否安装成功,成功会显示安装版本
  • 运行程序 在程序所在文件夹打开的命令行里 node xxx.js
Node包管理工具 npm
  • npm init 初始化
    生成package.json 在需要的文件夹内shift+右键 打开命令行

  • cnpm 国内npm镜像的客户端
    国内安装 -g是全局安装的意思

    npm install cnpm -g --registry=https://registry.npm.taobao.org
    
  • npm 常用命令

    • npm install xx 安装命令 可简写为 npm i xx

    • npm uninstall xx 删除命令 可简写为 npm un xx

    • npm update xx 更新某个包

    • npm idependencies中的依赖都装一遍

Node的模块

全局模块

定义:何时何地都能访问,不需要引用

  1. process.env 环境变量
    console.log(process.env);//打印所有的 环境变量
    console.log(process.env.path);//打印环境变量path
    
  2. process.argv 打印命令 返回一个数组
    //输入命令node test执行test.js
    console.log(process.argv);
    PS D:\VSCODE\node> node test node -v
    [
      'D:\\Program Files\\nodejs\\node.exe',
      'D:\\VSCODE\\node\\test',
      'node',
      '-v'
    ]
    let th = process.argv[3];
    console.log(th);//结果为-v
    
系统模块

定义:需要require(),但不需要单独下载

  1. path模块:用于处理文件路径和目录路径的实用工具

    let path = require('path')
    

    path中有几个方法:

    console.log(path.dirname('node/a/b/c/1.jpg');
    //打印结果为/node/a/b/c
    
    console.log(path.basename('node/a/b/c/1.jpg');
    //打印结果为1.jpg
    
    console.log(path.extname('node/a/b/c/1.jpg');
    //打印结果为.jpg
    

    可以通过这几个方法判断前端上传文件的类型

    console.log(path.resolve('/node/a/b/c' ,'../../','d'));
    //打印结果为node\a\d,返回上两级的结果中的d
    
    console.log(path.resolve(_dirname ,'xx.js'));
    //可以打印出这个文件的绝对路径
    
  2. fs模块:用于文件读写操作

    let fs = require('fs')
    

    fs中的方法

    异步

    fs.readFile('./a.text',(err,data)=>{
    	if(err){
    		console.log(err);//打印错误信息
    	}else{
    		console.log(data.toString());//打印文件内容,不加tostring是二进制表示方式
    	}
    })
    fs.writeFile('./b.text','写入内容',{flag:"a"}(err)=>{
    //如果不加	{flag:"a"},写入内容会覆盖前一次的,a即append
    	if(err){
    	    throw err
    	}
    }
    

    同步

    let data = fs.readFileSync('./a.text')
    conlise.log(data.toString());
    
    fs.writeFileSync('b.text','写入内容'
自定义模块

定义 :require自己封装的模块

  • exports

  • module

  • require

    • 新建一个模块,mod.js
    exports.a=1;//向exports中塞一个a,暴露出去
    let c = 3;  //c是模块中的,没有暴露出去外面是拿不到的
    
    • 新建一个index.js
    //引进模块mod再赋给变量 
    const mod1 = require('./mod');//  ./是指当前文件夹下  要引用当前文件夹下的mod.js   .js可以省略
    console.log(mod1.a);//结果为1
    console.log(mod1.c);//结果为undefined
    
  • require 特性

    1. 如果有路径,就去路径中找
    2. 如果没有路径,就去node_modules中找
    3. 上面都没有,再去node的安装目录中找
    //mod.js中
    module.exports={a:1,b:2}//导出一个对象
    
    //index.js中
    const mod1 = require('./mod')
    console.log(mod1.a);//结果为1
    console.log(mod1.b);//结果为2
    
    module.exports=function(){ //导出一个function
    	console.log('123');
    }
    mod1();//结果为123
    
    module.exports=class{ //导出一个class
    	constructor(name){
    	    this.name = name;
    	}
    	show(){
    	    console.log(this.name);
    	}
    }
    
    let p = new mod1('lily');//实例化
    p.show();//结果为lily
    
重点:HTTP模块
  • 服务器对象

    http.createServer() //可以帮我们快速的搭建一个服务器
    
  • 新建一个index.js

    let http = require('http');
    http.createServer((req,res)=>{
    	//console.log('连接成功');
    //返回访问的目录 req.url 
    //localhost:8080返回/ 就是根目录 
    //localhost:8080/index.html 返回 index.html
    	res.write('index');
    	res.end();
    //这样就结束了,访问的时候返回index
    //也可以简写 res.end('index1') 结果index1
    }).listen(8080)//监听这个端口,相当于去一栋楼里找人的门牌号,然后去浏览器访问这个端口,上面的信息就可以被打印出来了
    
  • 新建一个index.html,要把这个页面展示出来,用fs读取这个文件再展示

    let http = require('http');
    let fs = require('fs');//引入文件读写模块
    http.createServer((req,res)=>{
    	fs.readFile(`./${req.url}`,(err,data)=>{
    	    if(err){
    			res.writeHead(404);
    			res.end('404 not found ')
    		}else{
    			res.end(data)
    		}
    	})
    }).listen(8080)
    

Node中的数据交互

  • 数据报文分为:
    请求头:信息 url <32k
    请求体:数据 <2G
GET请求
  • 主要是获取数据,数据是放在URL里进行传输,容量小<32k

  • 结合创建服务器,拿到get请求中的数据

    let http require('http')
    //req就是请求发过来的东西
    //req.url发送请求过来的链接地址
    //发送数据要用表单或者ajax
    //创建一个表单的html,用户名,密码
    //action是指把数据提交到哪儿,后端的接口地址
    <form action="http://localhost:8888/aaa" method="GET">
      用户名:<input> type="text" name="username">
      密码:<input> type="password" name="password">
      <input> type="submit" value="提交">
    </form>
    http.createServer((req,res)=>{
    	console.log(req.url);
    
    }).listen(8888)
    
  • 启动服务 在表单输入用户密码 服务端得到结果

    /** /aaa?username=asdfas&password=123123 */
    
  • 中间就是传过来的信息,要得到其中的数据,引入URL模块

    let url =require('url');
    http.createServer((req,res)=>{
    //url.parse() 解析,两个参数,加上true会自动返回query经过处理的结果
        console.log(url.parse(req.url));
        let { pathname, query } = url.parse(req.url, true);
        console.log(pathname, query);
        console.log(query.username);
        //结果
        /**--------------------**/
    	Url {
    	  protocol: null,
    	  slashes: null,
    	  auth: null,
    	  host: null,
    	  port: null,
    	  hostname: null,
    	  hash: null,
    	  search: '?username=star&password=121',
    	  query: 'username=star&password=121',
    	  pathname: '/aaa',
    	  path: '/aaa?username=star&password=121',
    	  href: '/aaa?username=star&password=121'
    	}
    	//加上true参数之后
    	//query: [Object: null prototype] { username: 'star', password: '121' }
    	
    	/aaa [Object: null prototype] { username: 'star', password: '121' }
    	star
    	/**--------------------**/
    }).listen(8888)
    
POST请求
  • 数据是放在body里传输,容量大:<2G

    数据量大 分段传输 就是多次执行data

  • req.on()方法
    req.on('data',()=>{})req.on('end',()=>{})

    on中有个回调函数是拿到的数据data一般是文件图片之类的 数据不能是字符串
    计算机发送文件视频是以二进制的形式,所以使用这个buffer

  • end 表示结束 把数据放到数组里等拿完了一次性展示

    let http = require('http');
    
    http.createServer((req,res)=>{
    let reuslt = [];
    req.on('data',buffer=>{
        result.push(buffer);//数据分段执行多次
       /** console.log(buffer);
    //表单测试需将方法改为POST
    //用户名:aaa,密码:111
    //返回结果:<Buffer 75 73 65 72 6e 61 6d 65 3d 61 61 61 26 70 61 73 73 77 6f 72 64 3d 31 31 31>*/
    })
    
       req.on('end',()=>{
    //buffer 对象中的一个方法将结果拼起来
    //返回结果<Buffer 75 73 65 72 6e 61 6d 65 3d 61 61 61 26 70 61 73 73 77 6f 72 64 3d 31 31 31>
    //tostring转换,但是对文件和图片不行,需要使用模块处理post请求
            let data = Buffer.concat(result);
            console.log(data);
        
    /**console.log(result);
    //返回结果多了数组
    [
      <Buffer 75 73 65 72 6e 61 6d 65 3d 61 61 61 26 70 61 73 73 77 6f 72 64 3d 31 31 31>
    ]
        })
    */
    }).listen(8888)
    

案例

接口(API)
  • API:不同功能层之间的通信规则称为接口。
    前端不能通过JS直接操作数据库,接口帮着做这些事情

  • 参数:前端告诉接口,查询什么,什么就是参数,拿到这个参数再去查数据库

  • 返回值:拿到数据之后再返回给前端,叫做返回值

    接口名:’/login’
    请求方法:get
    参数:username,password
    返回值:JSON对象

    {
    	//错误信息 
    	err:1,
    	msg:"密码错误"
    }
    

    接口名:’/regist’
    请求方法:post
    参数:username,password phonenum email
    返回值:JSON对象

    {
    	//错误信息 
    	err:1,
    	msg:"注册失败"
    }
    
  • 接口文档

项目:实现登录和注册
写代码之前的准备工作
  • mkdir 文件夹名 ,新建项目文件夹;
  • cd 文件夹名 ,进到这个文件夹中;
  • npm init -y ,初始化 ;
  • npm i nodemon -D,监听更新,服务自动启动,不用手动一遍遍启动;
  • code ./,在vscode中打开代码。
正式开始
  • 项目下新建src文件夹

  • src中新建app.js,引入http模块,搭建服务器

    const http= require('http');
    
    http.createServer((req,res)=>{
    	
    }).listen(8080, () => {
        console.log('服务启动成功');
    })
    
  • 在package.json中配置启动脚本

    "scripts": {
    "start": "nodemon ./src/app.js"
    }
    
    • 启动项目使用命令npm (run) start 因为start是默认的,可以加run也可以不加,但是别的名称不能省略。

    • 问题记录:使用npm start报错 nodemon既不是内部命令也不是外部命令

    • 解决:看package.json的依赖中有没有引进nodemon,如果没有可以使用命令

      npm install --save-dev nodemon
      
  • API需求分析

    • 登录功能用GET请求; 注册功能用POST请求。

    • 首先是获取数据: 引入url模块,获取url中传的usernamepassword

    • 问题记录:- 视频中使用的是url.parse()方法,实际运行代码时出不来结果;

    • 解决在nodejs 11.0以后的版本上使用,编译器会提示已过期(since v11.0.0 - Use the WHATWG URL
      API),并推荐你使用URL

      使用URL类对url进行操作,详细见官方文档

      	const http= require('http');
      	const url = require('url');
      	const querystring = require('querystring');
      	http.createServer((req,res)=>{
      		//获取数据
      	    let path,getmyurl,post
      	    if (req.method == 'GET') {
      	        /* url 模块中的url.parse方法已经被废弃了*/
      	        //let { pathname, query } = url.parse(req.url, true)
      	        getmyurl = new URL('http://localhost:8080' + req.url);
      	        path = getmyurl.pathname
      	        //console.log('http://localhost:8080'+req.url);
      	        //console.log(path);
      	       //console.log(getmyurl.searchParams.get('username'));
      	        complete();//成功则调用函数
      	    }else if (req.method == 'POST') {
      	        let arr = [];
      	        path = req.url
      	        console.log(path);
      	        req.on('data', buffer => {
      	            arr.push(buffer);
      	        })
      	        req.on('end', () => {
      	            post = querystring.parse(Buffer.concat(arr).toString());//最后处理为json格式 如果有文件,这里不能直接使用toString
      	            complete()
      	        })
      	    }
      	    function complete () {}
      	}).listen(8080, () => {
      	    console.log('服务启动成功');
      	})
      
    • 根据客户端传递过来的不同的参数(用户名/密码) 查询是否存在,并且实现登录;

    • 实现 新增的一个用户 (用户名/密码)。

    • 要点记录:在使用 fs 模块之前先引入;

      const fs = require('fs')
      

      接下来是complete ()方法的实现

      function complete () {
          if (path == '/login') {
              res.writeHead(200, {
                  "Content-Type":"text/plain;charset=utf-8"
              })
              let username = getmyurl.searchParams.get('username')
              let password = getmyurl.searchParams.get('password');//接下来应该是判断数据库里有没有
              //使用let user = { admin:123456 }代替,写在http.createServer之外
              if (!user[username]) {
                  res.end(JSON.stringify({
                      err: 1,
                      msg:"用户名不存在"
                  }))
              } else if (user[username] != password) {
                  res.end(JSON.stringify({
                      err: 1,
                      msg:"密码错误"
                  }))
              } else {
                  res.end(JSON.stringify({
                      err: 0,
                      msg:"登录成功"
                  }))
              }
          } else if (path == '/regist') {
              res.writeHead(200, {
                  "Content-Type":"text/plain;charset=utf-8"
              })
              let {username,password} = post
              if (user[username]) {
                  res.end(JSON.stringify({
                      err: 1,
                      msg:"用户已存在"
                  }))
              } else {
                  user[username] = password //注册
                  res.end(JSON.stringify({
                      err: 0,
                      msg:"注册成功"
                  }))
              }
          } else {
          //fs模块需要在前面引入
              fs.readFile(`src${path}`, (err,data)=>{//读取页面文件src/login.html
                  if (err) {
                      res.end('404')
                  } else {
                      res.end(data)
                  }
              })
          }
      }
      
  • 页面实现

    • 要点记录:在使用 ajax 之前先引入jQuery,可以使用命令行安装

      npm i jQuery
      
    • 安装成功之后,在node_modules文件夹下的dist中就可以看到装好的jquey,再在页面中进行引用即可

      <script src="./static/jquery.min.js"></script>
      
    • 这里的是完善实现的部分代码:

      用户名:<input type="text" id="username"><br>
      密  码:<input type="password" id="password"><br>
      <button id="login">登录</button><br>
      <button id="regist">注册</button>
      
      <script>
          $('#login').click(function(){
              $.ajax({
                  url:"/login",
                  data:{
                      username:$('#username').val(),
                      password:$('#password').val()
                  },
                  dataType:"json",
                  success(res){
                      if(res.err){
                          alert(res.msg)
                      }else{
                          alert("登录成功!")
                          location.href="admin.html"//后台页面
                      }
                  }
              })
          })
          $('#regist').click(function(){
              $.ajax({
                  url:"/regist",
                  method:"post",
                  data:{
                      username:$('#username').val(),
                      password:$('#password').val()
                  },
                  dataType:"json",
                  success(res){
                      if(res.err){
                          alert(res.msg)
                      }else{
                          alert("注册成功!")
                      }
                  }
              })
          })
      </script>
      

写在最后

简单的实现了登录与注册,没有使用到数据库,后续学习可以加上。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值