zoukankan      html  css  js  c++  java
  • nodejs

    一:什么是nodejs?(node可以作为一个服务器)

       官网:https://nodejs.org/en/

       nodejs是一个基于chrome V8引擎的javascript运行时(可以解析和javascript语言,没有DOM和BOM

           *:nodejs不是一门语言,类似于浏览器,但是没有图形界面

       nodejs使用高效、轻量级的事件驱动、非阻塞(异步的)的I/O模型

           *:事件驱动

           *:IO:输入与输出(异步)

       nodejs的生态系统npm是目前最大的开源包管理系统

      使用nodejs可以做什么?

       网站开发、命令行应用程序

      MEAN (mongodb express angularjs nginx(类似于apache的服务器))

      LAMP(linux apache  mysql  php )

      WAMP(windows apache mysql php)

    传统的web交互模型:

    二:快速上手

    1.环境安装:

           (.msi格式的直接点击下一步安装)

              https://nodejs.org/en/download/

          打开cmd,输入 node -v 检查是否有node环境

    2.cmd中输入node 进入node环境

      cd:切换目录

     node + 文件名:使用nodejs执行该文件

      (实际是node.exe可执行程序读取了该文件,然后解析执行文件中的代码)

    3.文件操作

    //导入fs模块
    var fs=require('fs');
    //文件的写入
    //第一个参数:写入文件的路径(如果文件已经存在直接覆盖,如果不存在直接创建)
    //第二个参数:指定要写入文件的数据
    //注意:操作文件路径一定是相对路径或者绝对路径
    //        如果是相对路径,最好加上./
    //第三个参数:回调函数
    //回调函数需要接受一个参数:err
    //如果写入文件操作成功了,则err就是一个null
    //如果写入文件操作失败了,则err就是一个异常对象
    fs.writeFile('./data.txt','hello world ',function(err){
    	if(err){
    		throw err;
    	}
    	console.log('写入文件成功了');
    });
    

     注意:

             写文件时目录名最好不要出现中文、不要出现空格、文件名也不要写中文

    //导入文件模块
    var fs=require('fs');
    //第一个参数:尧都区的文件名
    //第二个参数:可选的,用来指定读取文件的编码格式(如:utf8),此处设置了编码,下面的data就不需要toString()
    //第三个参数:回调函数
    //    err:
    //        如果读取成功err就是null
    //        如果读取失败,err就是异常对象
    //    data:读取到的文件数据
    fs.readFile('./data.json','utf8',function(err,data){//记得写编码格式
       if(err){
            throw err;
       }
       //注意:此处获取的文件数据默认是二进制,要想获取要原始数据,需要将data.toString()
       console.log(data); 
    })

    4.服务器

    //导入服务器模块
    var http=require('http')
    //1.创建服务器
    var server=http.createServer()
    //2.给服务器实例对象server设置request请求事件处理函数
    //request事件处理函数需要接受两个参数:
    //Reques请求对象t:可以获取到客户端请求的一些数据,例如:url、请求方法
    //Response响应对象:可以用来给客户端发送响应数据 server.on('request',function(req,res){
    console.log(req.url) console.log(
    '有客户端请求进来了。。。。。')
    res.writeHead(200,{
    'Content-Type':'text/html;charset=utf8'
    })
    //使用res响应对象的write方法向本次请求发送响应数据
    //注意:可以多次使用write方法想客户端发送数据
    //建议给客户端发送数据的时候,告诉客户端你发的数据是什么类型
    res.write('hello')
    //发送完数据后要记得通知服务器响应完毕,即使只发送一个响应头也要记得end
    res.end()
    ************************************************************
    *//也可以直接把你要返回的数据写在end()里面,就可以不用写write()*
    * res.end('<h1>hello</h1>') *
    ************************************************************
    ===========================================================================
    =//实现重定向
    =//302状态码就表示重定向,浏览器看到302状态码后,会自动去响应报文头中找 Location属性=
    =res.writeHead(302,{
    = 'Location':'/' //重新跳转到首页 =
    =})
    =========================================================================== })
    //3.启动服务器,设置绑定一个端口号 //第一个参数:用来指定绑定的端口号。。。。 //第二个参数:可选的,指定绑定的ip地址, //第三个参数:回调函数 server.listen('3000',function(){ console.log('server is running at port 3000') console.log('please visit http://127.0.0.1:3000') })

     5.art-Template模板引擎

    哪个项目中要使用该模板就进入根路径,执行npm install art-Template,npm会在当前目录下找node_modules目录,如果没有,直接创建,并将要下载的问价添加到该文件夹,如果有,直接下载到该文件夹。

    //加载第三方包,不需要指定路径
    var template=require('art-Template')
    //1.调用template.compile函数,传入模板字符串
    //调用该函数之后会得到一个render渲染函数
    var render=template.compile('<h1>{{title}}</h1>')
    //2.调用render渲染函数,传入一个数据对象
    //返回解析替换后的字符串
    render({
        title:'hello world'
    })
    //条件表达式
    {{if admin}}
        <p>admin</p>
    {{else if code > 0}}
        <p>master</p>
    {{else}}
        <p>error!</p>
    {{/if}}
    //数组和对象的遍历
    {{each list as value index}}
        <li>{{index}} - {{value.user}}</li>
    {{/each}}
    亦可以被简写:
    {{each list}}
        <li>{{$index}} - {{$value.user}}</li>
    {{/each}}

    6.路径模块

    var url=require('url')
    //导入服务器模块
    var http=require('http')
    //导入处理post请求体的模块
    var querystring=require('querystring')
    //1.创建服务器
    var server=http.createServer()
    //2.给服务器实例对象server设置request请求事件处理函数
    server.on('request',function(req,res){
    //url模块中的parse方法可以将一个路径解析为一个对象
    // 可以得到一个路径中的 请求路径部分、查询字符串部分、端口号 等信息
    // 可以通过指定第二个参数为 true,自动将解析到的查询字符串解析为一个对象
    var urlObj=url.parse(req.url,true)
    // 拿到请求路径中的查询字符串对象(get请求的获取方式)
    var queryObj = urlObj.query
    //获取post请求中的请求体
    //表单post提交数据可能是很大的,所以post会把提交的数据进行分块传输
    //在服务端也需要一块一块的接收
    //通过监听req请求对象的data事件和end事件就可以接收
    var data=''
    req.on('data',function(chunk){
    //chunk接收到是二进制数据,和字符串拼接会自动调用toString()方法
    //二进制数据有一个length属性,获取到的就是二进制数据的字节
      data+=chunk
    })
    req.on('end',function(){
       //通过使用内置模块去二院string的parse将一个查询字符串转换为一个对象
      var body=querystring.parse(data)
    })
    //
    // 只拿到请求路径中的路径部分(不包含查询字符串)
    var pathname = urlObj.pathname
           console.log('有客户端请求进来了。。。。。')
    })
    //3.启动服务器,设置绑定一个端口号
    server.listen('3000',function(){
        console.log('server is running at port 3000')
        console.log('please visit http://127.0.0.1:3000')
    })

    三:nodejs中的模块化

    //一个文件就是一个模块
    //每个模块就是一个私有的作用域
    //默认模块内部定义的所有成员都只能在模块内部使用
    //require函数用来加载一个模块
    //    1.从头到尾执行模块中的代码
    //    2.可以得到模块内部的通信接口对象:module.exports
    var add=require('./add')
    //node中完全就是模块化的编程方式
    //每个js文件就是一个模块
    //每个模块就是一个私有作用域
    //在每个模块内部还提供了一个通信接口对象:module.eports接口对象
    //模块与模块之间可以通过require函数进行加载执行,并得到被加载模块内部的接口对象
    //模块与模块之间还可以互相依赖
    //module.exports用来向外暴露该模块内部的数据
    //在每个模块内部还提供了一个成员:eports接口对象
    //exports就是module.exports接口对象的一个引用
    //exports===module.exports
    //使用require注意事项:
    //   1.加载相对路径文件模块一定要以./或者../开头
    //   2.加载模块文件时后缀名可以省略,node中推荐省略后缀名
    //如果一个模块想要向外暴露一个单独的接口成员
    //例如:只暴露一个函数、字符串、数字、数组等成员
    //就需要通过module.exports接口对象赋值即可
    module.exports=function(){
        return x+y;
    }
    //注意:每个模块内部最终向外暴露的是module.exports
    //exports只是module.exports接口对象的一个引用
    //所以一旦给exports接口对象赋值,exports和 module.exports就失去引用关系

    核心模块(node内置)

    1.核心模块就是node内置的模块,需要通过唯一的标识名来进行获取。

    2.每一个核心模块基本上都只是暴露了一个对象,里面包含了一些方法供我们使用

    3.一般在加载核心模块的时候,变量的起名最好就和核心模块的标识名同名即可

        eg:`var fs=require('fs')`

    4.核心模块本质上也是文件模块

       核心模块已经被编译到了node的可执行程序,一般看不到

       可以通过查看node的源代码看到核心模块文件

       核心模块也是基于commonjs模块规范

      --------------------------------------------------------------------------------------------------------------------------------------

      -----------CommonJS规范加载模块是同步的,也就是说,只有加载完成,才能执行后面的操作。---------------------------------

      -----------AMD规范则是非同步加载模块,允许指定回调函数。

      -----------由于Node.js主要用于服务器编程,模块文件一般都已经存在于本地硬盘,所以加载起来比较快,-----------------------

      -----------不用考虑非同步加载的方式,所以CommonJS规范比较适用。----------------------------------------------------------

      -----------但是,如果是浏览器环境,要从服务器端加载模块,这时就必须采用非同步模式,因此浏览器端一般采用AMD规范。---

      --------------------------------------------------------------------------------------------------------------------------------------

    每个模块都提供了单一的功能,以下是常用的核心模块
    |     模块名称    |    模块作用       |
    | ---------------|----------------- |     
    |     fs         |   文件操作        |
    |     http       |   http服务       |
    |     path       |   路径处理        |
    |     url        |   处理url路径     |
    |   querystring  |   处理查询字符串   |
    |     os         |   操作系统相关     |
    |     net        |   socket网络编程  |
    |     util       |   工具函数        |
    |                |                  |

    模块的加载流程:

         *:优先从缓存加载

         *:在一个模块系统中,模块第一次被加载的时候会执行模块中的代码,通过把该模块的接口对象缓存起来。

         *:如果多次加载该模块,不会执行该模块中的代码了,直接从缓存中将该模块的接口对象取出来。

         *:加载模块得到的是内部接口对象的复制

         *:一旦第一次加载过后,拿到的是接口数据的备份,如果模块内部的成员被修改了,是不会影响到外部的使用。

    5.

    //读取文件的时候
    //如果文件是以/ 开头的,则直接去当前文件所属盘符根目录去找
    //读取文件的时候相对路径是以相对于执行node命令的时候所处的目录的
    var path=require('path')
    //拼接路径
    //join方法支持拼接多个路径,也支持拼接上一级路径
    //path.join('/a/b/c','./d','../e')
    path.join('__dirname','index.js')

    6.momentjs插件

    //转换中文格式
    moment.local('zh-cn')
    moment('20120311','YYYYMMDD').fromNow();//5 years age
    var time=new Date().getTime();//获取当前时间
    moment(time).startOf('second').fromNew();//x minutes age
    //获取当前时间并且格式化
    moment().format('YYYY-MM-DD hh-mm-ss')//2017-03-11 10:21:16

    四:node中的javascript

    ECMAScript
    console
    setInterval()
    setTimeout()
    clearInterval(id)
    clearTimeout(id)
    clearImmediate()
    setImmediate()
    __dirname
    __filename
    global
    process
    require()
    exports
    module

    五:MongoDB数据库

    - 官网:https://www.mongodb.com/
    - 菜鸟教程:http://www.runoob.com/mongodb/mongodb-tutorial.html
    - MongoDB 是一个面向文档存储(JSON)的 **非关系型** 数据库,可以用来存储网站应用程序的数据
      + MongoDB 将数据存储为一个文档,数据结构由键值(key=>value)对组成
      + MongoDB 文档类似于 JSON 对象。字段值可以包含其他文档,数组及文档数组
      + **非关系型** 后面给大家介绍 MySQL 数据库就会了解各大数据库的区别了
    - MongoDB 数据库是跨平台的,可以在 Linux、Mac OSX、Windows 等平台使用
    - MongoDB 诞生于 2009 年,由 10gen 团队创建

    安装MongoDB

     下载地址:https://www.mongodb.com/download-center
      + 根据自己的操作系统下载对应的数据库版本
    - 在 Windows 平台安装 MongoDB 数据库环境
      + 教程:http://www.runoob.com/mongodb/mongodb-window-install.html
      + 注意:所谓的 MongoDB 数据库环境其实是个服务,没有图形界面
    - 验证是否安装成功
      + 在终端中输入 `mongod --version` 命令进行查看
      + 如果能看到安装好的 MongoDB 数据库版本号,说明安装成功
    
    **注意:** 如果安装成功,但是执行 `mongod --version` 命令提示不是内部命令的错误,
    这个时候将 MongoDB 的安装目录中的 bin 目录配置到环境变量,然后再次尝试。
    
    启动和关闭 MongoDB 数据库服务程序
    > Tips:以下操作请确保你执行 `mongod --version` 能看到安装的服务版本号 `mongod` 命令用来启动 MongoDB 数据库,但是如果你第一次执行该命令,你会发现报错了。 这是因为 MongoDB 服务默认使用 `C:/data/db` 目录作为自己的数据存储目录, 这个时候如果没有该目录,则自己手动创建 `C:/data/db` 该目录,然后再次使用 `mongod` 启动数据库服务。 如果你想要使用别的数据存储目录,则可以通过 `mongod --dbpath=数据存储路径` 的形式启动 MongoDB 服务。 启动成功之后,你会发现控制台输出一大堆字符,并且没有退出,那这个时候表示 MongoDB 服务启动成功, 然后就可以把这个控制台最小化了,只要不关闭该窗口,MongoDB 服务实例就会一直运行。 如果想要关闭 MongoDB 服务,则可以在运行 MongoDB 服务的控制台中通过 `Ctrl + C` 关闭服务。 上述都是针对 64 位操作系统的操作步骤,如果是 32 位操作系统,则可以使用下面的方式启动 MongoDB 数据服务: ```bash $ mongod --dbpath 数据存储路径 --journal --storageEngine=mmapv1 ```
    //打开终端,输入'mongod'回车
    //'mongod'命令用来启动MongoDB数据服务
    //MongoDB服务默认将C:/data/db目录作为数据目录
    //所以需要先在C盘根目录下新建一个目录:C:/data/db
    //当执行mongod命令的时候,就会默认使用C:/data/db作为目录存储数据
    //如果你不想使用C:/data/db
    //mongod --dbpath=路径 --journal --storageEngine=mmapv1
    //一个计算机上只能安装一个mongodb应用服务实例
    //一个mongodb服务实力上可以创建多个数据库
    //一个数据库中可以有多个集合,一个集合中存储的就是文档(其实就是json对象)

    mongodb启动

    //打开终端输入mongod
    //再打开一个终端输入mongo
    //注意:是两个终端,不可以关闭其中任意一个
    //mongodb默认连接到127.0.0.1:27017

     操作数据库

    show dbs //查看mongodb服务中有哪些数据库
    use + '数据库名字'//切换数据库
        //如果该数据库不存在,会先进入该数据库
        //只有当你真正在该数据库中存储了一个集合之后,才会真正的创建数据库
    db //查看当前所属的数据库
    db.dropDatabase()//删除数据库(要先进入该数据库)
    db.collection.drop()//删除集合
    show collection//进入数据库查看所有的集合
    //增加数据 db.集合名.insert({name:jack,age:10})//插入数据
    //查询数据 db.集合名.find()//查询指定集合的所有数据 db.集合名.find().pretty()//格式化的形式读取集合数据
    //更新数据 db.集合名.update({更新条件},{要更新的数据对象})//默认更新所有,其实就是替换了 db.集合名.update({更新条件},{$set:{要更新的字段名:要更新的字段值}})//更新指定字段 //如果被更新的字段已经存在则直接更新,如果不存在,则直接向被匹配的文档中增加该字段 db.集合名.update({更新条件},{$set:{要更新的字段名:要更新的字段值}},{multi:true})//替换符合条件的多个 db.集合名.save({})//插入数据 db.集合名.save({_id:ObjectId('')},{key:value})//整体替换
    //删除数据 db.集合名.remove({匹配条件})//删除指定数据(默认删除匹配到的所有数据) db.集合名.remove({匹配条件},{justOne:true})//只删除符合条件的第一个

     nodejs操作mongodb

    //node中操作mongodb
    npm install mongodb  --save//安装mongodb模块
    
    var mongodb=require('mongodb')
    var MongoClient=mongodb.MongoClient()
    MongoClient.connect('mongodb://localhost:27017/数据库名',function(err,db){
        if(err){
            throw new Error('连接失败')
        }
        //添加数据
        db.collection('集合名')
        .insertMany([
            {key:value}
            ],function(err,result){
                if(err){
                    throw new Error('添加失败')
                }
            })
        //查询所有
        db.collection()
        .find({})//查询指定,则只需传入查询条件
        .toArray(function(err,docs){
            if(err){
                throw new Error('查询失败')
            }
        })
      //操作完数据库后,要关闭连接
      db.close()
    })

    六:express框架

    //初始化项目结构
    npm init  //在当前文件的根目录初始化一个package.json文件
     //(项目说明文件)
       name:项目名称
       version:版本
       description:项目描述
       main:入口文件
       scripts:{
               'test':'',
               'start':'node app.js'
       }
            *:当你在终端输入npm start的时候
            *:npm会自动找到package.json中的scripts中的start属性
            *:然后帮你执行start属性配置好的命令
       
       dependencies:{} 项目的依赖项(第三方包)
            *:npm install    //会自动找到package.json中的dependencies依次安装依赖包

    express基本使用

    //导入express模块
    var express=require('express')
    //1.调用express()得到一个app应用实例
    //express()就相当于http.createServer()
    //app就相当于原来的server
    var app=express()
    //在express中,render方法是需要单独来配置
    //对于express来说需要单独配置要使用的模板引擎
    //express 框架本身很灵活,很多功能需要单独配置才可以使用
    //相对于 express 来说,配置这些东西其实就是插件
    // 只要通过下面的配置,在 express 中就可以正常的使用 render 方法了
    // 一定要记得使用 render 的时候,加上后缀名
    app.render('', function(err, html){
      // ...
    });
    
    //2.给app应用实例挂载路由
    app.get('/',function(req,res){
      res.end('hello world')
    })
    //3.绑定端口,启动服务器
    app.listen('3000',function(){
        console.log('server is running.......')
    })

    七:nunjucks插件

    nunjuck基本配置使用:

    
    

    //nunjucks模板引擎----------nodejs中超牛的模板引擎
    npm install nunjucks --save


    var
    express = require('express') var nunjucks = require('nunjucks')
    var app = express() // 在 express 中,render方法需要单独配置的 // 对于express来说,需要单独配置使用的模板引擎 // 相对于express来说,配置这些东西其实就是插件 //只要通过下面的配置,在express中就可以正常使用render方法了
    nunjucks.configure('views',{
    express:app
    }) app.get('/',function(req,res){
    res.render('index.html')
    })
    app.listen(3000, function () { console.log('running...') })

     nunjucks模板引擎处理静态资源:

    var express = require('express')
    var nunjucks = require('nunjucks')
    var path = require('path')
    var router = require('./router')
    var bodyParser = require('body-parser')
    var app = express()
    
    // 在 express 中暴露公共资源
    // 在 express ,也是通过配置的形式提供对静态资源的处理
    // 第一个参数用来配置静态资源的前缀路径
    // 第二个参数用来指定该模糊路径查找的磁盘路径
    // 第一个参数是可选参数,可以不指定
    //    如果不指定第一个参数,则请求的时候,就不要加任何前缀
    //    ,直接请求该目录中的资源路径就可以了
    //    例如你要请求 node_modules/bootstrap/dist/css/bootstrap.css
    //    则请求的时候,不要加 /node_modules 前缀,直接 /bootstrap/dist/css/bootstrap.css 就可以了
    app.use('/node_modules',express.static(path.join(__dirname, 'node_modules')))
    app.use('/public', express.static(path.join(__dirname, 'public')))
    
    //配置nunjucks模板引擎
    // noCache 用来指定缓存配置,默认是 false
    var env = nunjucks.configure(config.viewPath, {
      noCache: true
    })
    env.express(app)
    
    
    // 配置解析表单 post 提交数据的插件
    // 该插件的名字叫:body-parser
    // 可以专门用来和 express 结合使用,解析请求体中表单 post 提交的数据
    // 只要使用了下面的配置,该插件会自动帮你把表单 post 请求体数据解析成一个对象,
    // 然后挂载给 req 请求对象的 body 属性
    // 也就是说,在后面的所有的处理函数中,如果想要拿到表单 post 请求体数据,
    // 直接通过 req.body 来拿就可以了
    app.use(bodyParser.urlencoded({ extended: false }))
    app.use(bodyParser.json())
    
    // 2. 给 app 应用实例挂载路由
    app.use(router)
    
    // 3. 绑定端口,启动服务器
    app.listen(3000, function () {
      console.log('running...')
    })

     八、改完代码自动重启服务器

    通过使用第三方命令行工具 `nodemon` 来解决改完代码重启服务器的问题
    
    `nodemon` 是一个基于 Node 开发的一个第三方命令行工具,要想使用,在终端中通过:
    
    ```bash
    $ npm install --global nodemon
    ```
    
    安装完毕之后,把原来使用 `node app.js` 替换成 `nodemon app.js`,
    这样的话就可以实现服务器端代码修改,直接自动重启服务器。

    注意:全局命令行工具一次安装,永久使用,以后再使用,就不用再次安装了。

    九、cnpm

     通过 cnpm 改变镜像源地址的方式解决 npm 被墙问题
    
    - http://npm.taobao.org/
    
    淘宝 NPM 镜像,这是一个完整 npmjs.org 镜像,你可以用此代替官方版本(只读),同步频率目前为 10分钟 一次以保证尽量与官方服务同步。
    
    只需要在下载包的时候,加上 `--registry=https://registry.npm.taobao.org`,那这样的话就会通过
    淘宝的 `cnpm` 去下载,例如:
    
    ```bash
    $ npm install 包名 --registry=https://registry.npm.taobao.org
    ```
    
    这样话虽然可以解决,但是每次下载包的时候,还要自己手动加上这个参数,有一个更好的:
    
    
    ```bash
    $ npm config set registry=https://registry.npm.taobao.org
    ```
    
    该命令表示设置 npm 下载的镜像源地址为: `https://registry.npm.taobao.org`,
    只要做了执行了该命令,那以后所有的 `install` 都会使用该地址。
    
    如果想要删除该配置,使用下面的命令:
    
    ```bash
    $ npm config delete registry
    ```
    
    还可以通过下面的命令查看当前 npm 的配置列表:
    
    ```bash
    $ npm config list
    ```

     十、requirejs基本使用

         

  • 相关阅读:
    并发与多线程
    java多线程--死锁
    java变量
    StringStringBufferStringBuilder区别
    java8新特性
    spring自动装配和通过java实现装配
    CSP -- 运营商内容劫持(广告)的终结者
    【Composer】实战操作二:自己创建composer包并提交
    【个人重点】开发中应该重视的几点
    【Composer】实战操作一:使用库
  • 原文地址:https://www.cnblogs.com/luxiaoxiao/p/6528364.html
Copyright © 2011-2022 走看看