zoukankan      html  css  js  c++  java
  • node笔记1

    node

    day1

    node中的JavaScript

    • 没有DOM,BOM
    • 模块系统:
      • 内置模块:fs文件操作、http服务器操作、path路径操作、os系统信息操作
      • 第三模块:比如,express、art-template、ejs、jade(pug)、handlebars、nunjucks
      • 自定义模块

    补充

    • return的作用
      1、返回结果
      2、结束代码的执行
    • jQuery中的each和foreach
      • 伪数组是对象
      • 对象的原型链中没有forEach
      • 对象的原型是object.prototype
      • jQuery不是专门用来遍历jquery元素的
        • 1、方便的遍历jquery对象
        • 2、在不兼容forEach的低版本浏览器中使用jQuery的each方法
      • jQuery的实例对象不能使用forEach方法,如果想用必须转为数组
        [].slice.call($('div')).forEach(function(item,index) {console.log(item)})
    Array.prototype.myslice=function() {
      let start=0
      let end = this.length
      if(arguments.length===1) {
        start=arguments[0]
      }else if(arguments.length===2) {
        start=arguments[0]
        end=arguments[2]
      }
      let tmp=[]
      for(let i=start;i<end;i++) {
        tmp.push(this[i])
      }
      return tmp
    }
    let fakeArr={0:'abc',1:"kris",2:"lisa",length:3};
    let arr=[].myslice.call(fakeArr)
    console.log(arr);
    

    http核心模块(创建编写服务器)

    • 服务器
      • 对数据提供服务
      • 发请求,接受请求,处理请求,发送响应
    //1、加载模块
    const http = require('http')
    //2、返回server实例
    const server=http.createServer()
    //3、注册requset事件
    server.on('requset',function(req,res){
      if(req.url==='/') {
        res.end("我是首页")
      }
    })
    //4、绑定端口号,启动服务器
    server.listen(3000,function() {console.log('server is running')})
     // http.createServer(function(req,res) {}).listen(port,function() {})
    
    • req:request,res:response
    • req.url 请求路径
    • res.write() 给客户端发送响应数据,可以使用多次
    • res.end() 结束响应(如果发送了响应数据,必须写)
    • !!!通常是直接使用res.end(响应内容)
    • 响应内容只能是二进制或者字符串
    • 响应内容类型:
      • 服务器默认发送的是utf-8(chcp 65001)的编码内容,浏览器默认按当前操作系统的默认编码的解析
      • 中文操作系统默认是gbk(chcp 963)
      • res.setHeader('Content-type','text/plain;charset=utf-8')
      • 文本:text/plain,html:text/html,图片:image/jpeg(图片不需要指定编码,一般说的编码是指字码)
      • 帮助: https://www.oschina.net/

    fs模块(操作文件)

    • 执行node中的js文件:node xxx.js
    • 引入fs模块:let fs = require('fs')
    • 读取文件
      • fs.readFile("url",function(err,data) {})
      • 成功:err :null, data:读取到的数据
      • 失败:err :错误对象 data :undefined没有数据
      • 注意:读取到的是二进制数据
    • 写文件
      • fs.writeFile("url","content",function(err) {})
      • 成功:文件写入成功,err:null
      • 失败:文件写入失败,err:错误对象
    • 读取文件目录
      fs.readdir('url', function (err, files) {})

    path路径操作

    • 引入模块 let path = require('path')
    • path.extname('url') 文件扩展名

    os操作系统信息

    • 引入模块 let os = require('os')
    • cpu信息 os.cpus()
    • 内存信息 os.totalmem()

    url模块

    • 引入模块 let url = require('url')
    • url.parse("url") 解析请求路径中的查询字符串
    • url.parse("url",true)

    day2

    模块化

    • require(一个方法),
      • 对于核心模块:作用是加载模块
      • 对于文件模块:
        加载文件模块并执行里面的代码
        拿到被加载文件模块导出的接口对象
    • 在node中,模块有三种:
      • 1、具名的核心模块:如fs,http 【require('fs')】
      • 2、用户自己编写的文件模块:就是js文件 【require('url')】
      • 3、第三方模块
    • 在node中,没有全局作用域,只有模块作用域
    • 模块作用域:外部访问不到内部,内部也访问不到外部
    • 模块与模块通信:先require()加载模块,再exports导出需要使用的数据方法等。export默认是一个空对象

    使用art-template

    • 浏览器中:
      1、
      2、template('script的id标签',{})
    • node中
      1、安装:npm install art-template
      2、加载包:let template = require('art-template')
      3、template.render(模板字符串,{})
      注意:render方法里面接收的必须是要字符串

    服务端渲染和客户端渲染的区别

    • 客户端最少两次请求,发起ajax在客户端使用模板引擎渲染
    • 客户端难道的就是服务端已经渲染好的
    • 客户端渲染不利于SEO搜索引擎优化
    • 服务端渲染是可以被爬虫爬取到的,客户端异步渲染很难被爬取到
    • 真正的网站是两种结合来做的

    ip地址和端口号

    • 计算机中只有一个物理网卡,而且同一个局域网中,网卡的地址必须是唯一的
    • 网卡是通过唯一的ip地址来进行定位的
    • ip地址 用来定位 计算机
    • 端口号 用来定位 具体的应用程序
    • 端口号范围:0-65536

    处理网站中的静态资源

    • 浏览器在解析html文件中,如果发现:link,script,img,iframe,video,audio等带有src或者href(link)属性标签的时候,浏览器会对这些资源发起新的请求
    • 统一请求静态资源,全部以public开头

    以前表单是如何提交的

    • 表单中需要提交的表单控件元素,必须具有name属性
    • 表单提交分为:
      • 默认的提交行为
      • 表单异步提交
    • action="url" ,method="post或get"

    如何通过服务器让客户端重定向

    • 方法一:
      • 状态码设置为302 临时重定向
        res.statusCode=302
        301:永久重定向 浏览器会记住,去过一次以后,下次直接去
        302:临时重定向 浏览器不会记住,告诉你往哪里去
      • 在响应头中通过Location 告诉客户端往哪重定向
        res.setHeader('Location','newUrl')
      • res.end() 结束响应
    • 方法二:
      • res.redirect('newUrl')
      • res.end() 结束响应

    day3

    什么是模块化?

    • 文件作用域
    • 通信规则
      • 加载require
      • 导出exports exports是一个空对象
    • 原理
      • 在node中,某个模块内部都有一个自己module对象
      • 该module对象中,有一个成员:exports(一个空对象)
      • 如果需要导出成员:module.exports.属性或方法=值 或 exports.属性或方法
      • exports=== module.exports
      • 在require的时候,谁require,谁就得到module.exports
      • returen 的是module.exports
      • 当导出单个对象的时候
        不能exports=xxx
        module.exports=xxx
    • 真正使用的时候
      导出多个:exports.xxx=xx或moudle.exports={}
      导出单个:module.exports=xx 拿到的就是函数或字符串

    npm

    网址:https://www.npmjs.com/

    常用命令
    • npm --version
    • npm install --global npm 升级npm
    • npm init
    • npm init -y
    • npm install 一次把dependencies中的选项都安装
    • npm install 包名 只下载包
    • npm i --save 包名 下载并保存依赖
    • npm i -S 包名 下载并保存依赖
    • npm uninstall 包名 只删除包
    • npm uninstall 包名 --save 删除包和依赖
    • npm un 包名 --save 删除包和依赖
    • npm --help 帮助
    npm被墙

    express感知

    • 1 安装:npm i -S express
    • 2 引包:let express = require('express')
    let express = require('express')
    let app = express()
    // 静态资源
    // 当第一个参数省略;/文件路径
    // app.use(express.static('./public/'))
    // 访问:/public/文件路径
    app.use('/public/',express.static('./public/'))
    // 访问:/xxx/文件路径
    // app.use('/xxx/',express.static('./public/'))
    
    // 当服务器收到get请求/ 的时候,执行回调处理函数
    app.get('/',function(req,res) {
     res.send('hello express')
    })
    // 请求/about,执行回调函数
    app.get('/about',function(req,res) {
     res.send('我是about')
    })
    app.listen(3000,function() {
     console.log('app is running http://127.0.0.1:3000/');
    })
    

    day4

    模板标识符

    • / 是相对于当前磁盘
    • 文件操作中的相对路径省略./ ,我们使用的所有文件操作的API都是异步的,就像ajax请求一样
    • 在模块加载中的相对路径./必须写

    修改代码自动重启服务器

    • nodemon是一个基于node.js开发的第三方命令行工具
    • 1 安装:npm i nodemon --global
    • 2 使用:nodemon xx.js

    查看3000端口是否被占用?

    • netstat -ano|findstr "3000"
    • tasklist|findstr "占用的端口进程ID"
    • taskkill /f /t /im 进程名称

    express中使用art-template

      npm install --save art-template
      npm install --save express-art-template
    
    • 2 配置和使用
    // 配置使用art-template: 
    // 1 使用:res.rend('xx.art',{模板数据})
    // 2 注意:xx.art 就是html模板 (不能写路径,默认会去项目中的views目录找该模板文件)
    // 3 如果想要修改默认的views目录为xxx目录:
        //  app.set('xxx',render函数的默认路径)
    // app.engine('art', require('express-art-template'));//art表示以.art结尾的文件
    // res.render('404.art')
    let express= require('express')
    let app = express()
    app.use('/public/',express.static('./public'))
    app.engine('html', require('express-art-template'))
    app.get('/',function(req,res) {
      res.render('index.html')
    })
    app.listen(3000,function() {
      console.log("app is running http://127.0.0.1:3000/");
    })
    

    express配置表单post

    let express = require('express')
    let bodyParser = require('body-parser')
    let app = express()
    // 静态资源(开发public目录下的所有资源)
    // 当第一个参数省略;/文件路径
    app.use('/public/', express.static('./public/'))
    let comments = [{
        name: '张三',
        message: '今天天气不错!',
        dateTime: '2015-10-16'
      },
      {
        name: '张三2',
        message: '今天天气不错!',
        dateTime: '2015-10-16'
      },
      {
        name: '张三3',
        message: '今天天气不错!',
        dateTime: '2015-10-16'
      },
      {
        name: '张三4',
        message: '今天天气不错!',
        dateTime: '2015-10-16'
      },
      {
        name: '张三5',
        message: '今天天气不错!',
        dateTime: '2015-10-16'
      }
    ]
    //art表示以.art结尾的文件;html表示以.html文件结尾
    // app.engine('art', require('express-art-template'));
    // res.render('404.art')
    app.engine('html', require('express-art-template'))
    // 配置body-parser
    app.use(bodyParser.urlencoded({extended: false}))
    app.use(bodyParser.json())
    
    app.get('/', function (req, res) {
      res.render('index.html', {
        comments
      })
    })
    app.get('/post', function (req, res) {
      res.render('post.html')
    })
    /*app.get('/pinglun', function (req, res) {
      // req.query只能拿get请求参数
       let comment = req.query
       comment.dateTime = getDate();
       comments.unshift(comment)
       res.redirect('/')
     })
    */
    // 当以post请求 /post 的时候执行指定的处理函数
    // 通过不同的请求方法,同一路径可以使用多次
    app.post('/post', function (req, res) {
      /*在express中获取post请求体数据?
      (http://expressjs.com/en/resources/middleware/body-parser.html)
      1 安装: npm install body-parser
      2 引包:let bodyParser = require('body-parser')
      3 配置 // 配置后,在req请求对象上就会多次一个属性:body
          app.use(bodyParser.urlencoded({ extended: false }))
          app.use(bodyParser.json())
      */
      let comment = req.body//通过req.body 获取请求参数
      comment.dateTime = '2020-3-9';
      comments.unshift(comment)
      res.redirect('/')
    })
    app.listen(3000, function () {
      console.log("app is running http://127.0.0.1:3000/");
    })
    
    

    在express中获取post请求体数据:req.body

    let express = require('express')
    let bodyParser = require('body-parser')
    let app = express()
    // 配置后在req请求对象上就会多次一个属性:body
    app.use(bodyParser.urlencoded({ extended: false }))
    app.use(bodyParser.json())
    

    express获取表单get中的请求参数:req.query

    express中如何吧app.get/post部分提到router.js文件中?

    • 方法一:
      • 在router.js中
        module.exports=function(app){app.get('/xx/',function(req,res){xx})}
      • app.js中:
        let router= require('./router.js')
        router(app)
    • 方法二(推荐):
    • router.js文件中
    let express = require('express')
    let router = express.Router()
    router.get('/xxx', function (req, res) {})
    module.exports=router
    
    • app.js中
      let router=require('./router')
      app.use(router)

    day5

    回调函数

    异步操作总结:

    1 回调函数
    2 定时器
    3 事件监听
    4 promise
    5 async await

    JavaScript天生不支持模块化

    • require,exports是node.js才有的
    • CommonJS,AMD,CMD,UMD,,EcmaScript 6 Module官方规范都是为了解决JavaScript模块化问题

    所有未处理的路径,都会响应xxx

    app.use(function(req,res) {
      res.send('xxx')
    })
    

    MongoDB安装

    开启关闭MongoDB数据库

    • 1 启动:mongod
    * mongodb默认使用执行mongodb命令所处磁盘目录下的/data/db 作为自己的数据存储目录
    * 所以在第一次执行该命令前先收到创建一个 /data/db
    * 如果想要修改默认的数据存储目录: mongod --dbpath=数据存储目录路径
    mongod 
    
    • 停止: ctrl+c

    连接和退出数据库

    • 连接 :再开启一个命令窗口 -> mongo (该命令默认连接本机的MongoDB服务)
    • 退出:在连接状态 -> exit

    mongoDB基本命令

    • show dbs 查看显示所有数据库
    • db 查看当前操作的数据库
    • use 数据库名称 切换到指定数据库(没有会新建)
    • db.students.insertOne({"name":"jack"}) 插入数据 (插入students)
    • show collections 查看数据库中的数据
    • db.students.find() 查看students里面的所有数据

    在node中如何操作MongoDB数据

    // 设计schema发布module
    let mongoose = require('mongoose')
    let Schema = mongoose.Schema
    // 1、连接数据库
    // 指定连接的数据库不需要存在,当插入第一条数据的时候会被自动创建
    mongoose.connect('mongodb://localhost/test'})
    // mongoose.connect('mongodb://localhost/test',{useMongoClient:true})
    
    // 2、设计集合结构(表结构)
    // 约束的目的是为了保证数据的完整性,不要有脏数据
    let userSchema = new Schema({
      username: 
        type: String,
        required: true //表示必须有这个数据
      },
      password: {
        type: String,
        required: true
      },
      email: {
        type: String,
        required: true //表示必须有这个数据
      }
    });
    // 3、将文档结构发布为模型
    // mongoose.model方法用来把一个架构发布为model
    // 第一个参数,必须首字母大写的单数形式,mongoose会自动生成 小写复数 的集合名称
    // 第二个参数:架构Schema
    // 返回值:模型构造函数
    let User = mongoose.model('User', userSchema)
    
    // 4、使用构造函数对集合中的数据进行操作
    let xjm = new User({
      username: "xjm",
      password: '12345',
      email: "xjm.com"
    })
    /* ###### 增加数据  ###### */
    // xjm.save((err, ret) => {
    //   if (err) {
    //     return console.log("保存失败");
    //   }
    //   console.log("保存成功");
    //   console.log(ret);
    // })
    
    /* ###### 查询数据  ###### */
    /* ###### 查询全部数据 */
    User.find((err, ret) => {
      if (err) {
        return console.log("查询失败");
      }
      console.log("查询成功");
      console.log(ret);
    })
    /* ######按条件查询所有 */
    // User.find({username:'zs'},(err, ret) => {
    //   if (err) {
    //     return console.log("查询zs失败");
    //   }
    //   console.log("查询zs成功");
    //   console.log(ret);
    // })
    /* ######按条件查询一个 */
    // User.findOne({username:'zs'},(err, ret) => {
    //   if (err) {
    //     return console.log("查询zs失败");
    //   }
    //   console.log("查询zs成功");
    //   console.log(ret);
    // })
    /* ######查询第一个 */
    // User.findOne((err, ret) => {
    //   if (err) {
    //     return console.log("查询one失败");
    //   }
    //   console.log("查询one成功");
    //   console.log(ret);
    // })
    
    /* ###### 删除数据 ######*/
    /* ##### 根据条件删除所有*/
    // User.remove({username:'xjm'},(err, ret) => {
    //   if (err) {
    //     return console.log("删除失败");
    //   }
    //   console.log("删除成功");
    //   console.log(ret);
    // })
    /* ###### 根据条件删除一个*/
    // User.findOneAndRemove({username:'xjm'},(err, ret) => {
    //   if (err) {
    //     return console.log("删除失败");
    //   }
    //   console.log("删除成功");
    //   console.log(ret);
    // })
    /* ###### 根据id删除一个*/
    // User.findByIdAndRemove("5e6796c24b7a312ef8669f50",(err, ret) => {
    //   if (err) {
    //     return console.log("删除失败");
    //   }
    //   console.log("删除成功");
    //   console.log(ret);
    // })
    
    /* ###### 更新数据 ######*/
    /* ###### 根据指定条件更新所有 */
    // User.update({name:"xjm"}, {
    //   password: "88888"
    // }, (err, ret) => {
    //   if (err) {
    //     return console.log("更新失败");
    //   }
    //   console.log("更新成功");
    // })
    /* ###### 根据id更新一个 */
    // User.findByIdAndUpdate('5e679da0d6ec08285cee6c06', {
    //   password: "88888"
    // }, (err, ret) => {
    //   if (err) {
    //     return console.log("更新失败");
    //   }
    //   console.log("更新成功");
    // })
    
    /* ###### 根据指定条件更新一个 */
    // User.findOneAndUpdate({name:"xjm"}, {
    //   password: "88888"
    // }, (err, ret) => {
    //   if (err) {
    //     return console.log("更新失败");
    //   }
    //   console.log("更新成功");
    // })
    

    MongoDB数据库的基本概念

    • 数据库 :可以有多个
    • 集合(表):可以有多个
    • 文档(表记录):可以有多个

    在浏览器看xx.json文件

    • npm i --global json-server
    • json-server --watch xx.json

    day6

    Node中的其他成员()

    • 在每个模块出来,require,exports,还有
    • __dirname 动态获取当前文件模块所属目录的绝对路径
    • __filename 动态获取当前文件的绝对路径

    node中:文件操作(fs)中的路径

    • 相对路径就是相对于执行node命令行所处的路径
    • 解决:path.join(__dirname,'文件名')

    blog-demo路由设计

    路径 方法 get参数 post参数 是否需要登录 备注
    / get 渲染首页
    /register get 渲染注册
    /register post email,nickname,password 处理注册
    /login get 渲染登录
    /login post email,password 处理登录
    /logout get 处理退出请求
    • 安装 npm i -S body-parser
    • 配置
    let express= require('express')
    let bodyParser= require('body-parser')
    let app =   express()
    // 通过req.body来获取表单post的数据
    app.use(bodyParser.urlencoded({extended:false}))
    app.use(bodyParser.json())
    

    使用MD5 (加密)

    • 安装 npm i blueimp-md5
    • let md5= require('blueimp-md5')
    • 使用 md5(要加密的内容)

    表单提交

    • 表单具有默认提交行为,默认都是同步的
    • 表单同步提交之后,无论服务器响应的是什么,都会直接把响应的结果覆盖掉当前页面

    服务端重定向针对异步请求是 无效的

    express-session

    • 安装 npm i -S express-session

    • 引入 let session= require("express-session")

    • 配置

    • 使用:通过req.session来访问和设置Session成员

      • 添加 Session数据:req.session.key=value
      • 访问 Session数据:req.session.key
  • 相关阅读:
    内聚和耦合的举例
    OneZero第四周第五次站立会议(2016.4.15)
    OneZero第四周第四次站立会议(2016.4.14)
    OneZero团队Beta发布剧透
    PSP(4.6——4.12)以及周记录
    关于“内聚和耦合”
    CSV 注入实战
    BurpSuite 一些小技巧
    博客园URL跳转钓鱼
    【Demo 0005】Android 资源
  • 原文地址:https://www.cnblogs.com/xiaojimeng/p/12821505.html
Copyright © 2011-2022 走看看