Node学习(一)

温馨提示: 通过nvm安装,若之前安装过node.js,得把之前安装过的node.js卸载掉

一、Node安装

(一)直接安装

直接到官网下载即可

(二)nvm方式安装

nvm :node.js版本管理工具

Windows 操作系统的 nvm 下载地址:.
2.1第一步: 点击下载Node学习(一)_第1张图片
2.2第二步: 解压后点击安装
2.3第三步: 自己在文件里创建个dev文件夹【目的:方便查找】,入下图安装
Node学习(一)_第2张图片
2.4第四步: node.js(镜像文件)、建立安装到dev里面,便于查找
Node学习(一)_第3张图片
2.5第五步: 查看是否成功状态
Node学习(一)_第4张图片
2.6第六步: 配置文件–打开刚刚的dev文件【若没有node.js,请自行创建即可】
2.7第七步: 修改dev/nvm下的 settings.txt 文件

  • root:nvm的安装位置(自动生成)
  • path:指定的 nodejs 的快捷目录(自动生成)
  • node_mirror:设置 下载 node 时的镜像
  • npm_mirror:设置 下载 npm 时的镜像
    例如:
root: E:\tools\dev\nvm
path: E:\tools\dev\nodejs
node_mirror: http://npm.taobao.org/mirrors/node/
npm_mirror: https://npm.taobao.org/mirrors/npm/

③输入nvm install 15开始安装:

(三)nvm常用命令

  • nvm install :node 安装指令
    • nvm install 0.0.1 :指定安装的版本
      • nvm install 9 :指定大版本,会安装这个大版本的最新版本
    • nvm install latest : 安装最新版本
  • nvm list :查看本地已安装的node版本
  • nvm use
    • nvm use 0.0.1 :启用已安装的版本
    • uninstall 版本:卸载

二、commonjs规范

2.1、commonjs

map:

- [commonjs模块化规范特点](#commonjs模块化规范特点)
- [module对象](#module对象)
- [module.exports](#module.exports)
- [exports变量](#exports变量)
- [require](#require)
- [commonjs的模块加载机制]

2.2、common.js模块化规范特点

(一)所有代码都运行在模块作用域,不会污染全局作用域(每个文件就是一个模块,有自己的作用域,在一个文件里面定义的变量、函数、类都是私有的,对其他文件不可见)
(二)模块可以多次加载,但是只会在第一次加载时运行一次,然后运行结果就被缓存了,以后再加载,就直接读取缓存结果,要想让模块再次运行,必须清除缓存;
(三)模块加载的顺序,按照其在代码中出现的顺序;

2.3、module对象

Node内部提供一个 Module 构建函数。所有模块都是 Module 的实例。

每个模块内部,都有一个module对象,代表当前模块。它有以下属性。

  • module.id 模块的识别符,通常是带有绝对路径的模块文件名。
  • module.filename 模块的文件名,带有绝对路径。
  • module.loaded 返回一个布尔值,表示模块是否已经完成加载。
  • module.parent 返回一个对象,表示调用该模块的模块。
  • module.children 返回一个数组,表示该模块要用到的其他模块。
  • module.exports 表示模块对外输出的值。

通过 exportsmodule.exports 向外暴露成员。

2.4、module.exports

module.exports 属性表示当前模块对外输出的接口,其他文件加载该模块,实际上就是读取 module.exports 变量。

// 导出  test1.js
module.exports = 123
// 导入
let a = require('./test1')
console.log('a -->', a);    // 123

2.5、exports变量

// 导出  test1.js	
module.exports = 123

// 导入
let a = require('./test1')
console.log('a -->', a);    // 123

为了方便,Node为每个模块提供一个exports变量,指向module.exports。

// 导出  test1.js
exports.xxx = 'hello'

// 导入
let a = require('./test1')
console.log( a.xxx )    // hello

// 导出  test1.js
let ee = {
    fn: function(){
        console.log('err')
    }
};
exports.xxx = ee
// 导入
let rr = require('./test1')
console.log(rr)             // {xxx: {fn: function(){}}}
console.log(rr.xxx.fn())    // 'err'

2.6、案例理解

正常情况下:

//导出:
let n =123;
function fn(){
     
    console.log(666)
}
let obj = {
     
    name: 'hello',
    age: 18,
    fn(){
     
        console.log(888);
        return 'ok'
    }
}
module.exports.fn = fn;
module.exports.num = n;
module.exports.obj = obj;

function init(){
     
    console.log(1123);
}
exports.init = init;
//导入
let fn = require('./module.js');
console.log('fn----->',fn);

结果
Node学习(一)_第5张图片
非正常情况下:

//导出
let n =123;
function fn(){
     
    console.log(666)
}
let obj = {
     
    name: 'hello',
    age: 18,
    fn(){
     
        console.log(888);
        return 'ok'
    }
}
module.exports.fn = fn;
module.exports.num = n;
module.exports.obj = obj;

function init(){
     
    console.log(1123);
}
exports.init = init;

//直接给module赋值的话,就相当于切断了指向obj的线,将会直接把值暴露出来
module.exports = init;
console.log('exports---->',typeof(exports));
//导入
let fn = require('./module.js');
console.log('fn----->',fn);

结果:
在这里插入图片描述
因此,总结如下:
Node学习(一)_第6张图片

2.7、require

Node 使用 CommonJS 模块规范,内置的 require 命令用于加载模块文件。

require命令的基本功能是,读入并执行一个 JavaScript 文件,然后返回该模块的 module.exports 对象。如果没有发现指定模块,会报错。

require 参数的几种情况

  1. require(’./xxx’) : 加载本地模块
  2. require(’/xxx/yyy/zzz/aaa’) : 加载绝对路径的模块
  3. require(‘xxx’) : 加载官方模块 或 第三方包

弊端

let fn =() => {
     
    console.log(666);
}

let fn1 =() => {
     
    console.log(6661);
}

module.exports = fn1;
module.exports = fn;
let fn = require('./module.js');

console.log('fn----->',fn);

结果只会是一个函数
在这里插入图片描述

三、Path

3.1目录、文件、扩展名

  • path.dirname(path) :返回 path 的目录名,类似 Unix 的 dirname 命令
  • path.basename(path[,ext]) :返回 path 的最后一部分,类似 Unix 的 basename 命令
  • path.extname(path) :返回 path 的扩展名
console.log(path.dirname('/foo/bare/styd/query'));//返回当前/foo/bare/styd

console.log(path.basename('/foo/bare/styd/query'));//得到query

console.log(path.extname('aaaa/bbbb/cccc/dddd/index.html'));//得到.html

3.2路径规范化和解析、拼接

  • path.normalize(path) :规范化路径
  • path.resolve([…path]) :将路径或路径片段的序列解析为 绝对路径 如果没有传入 path 片段,则 path.resolve() 将返回当前工作目录的绝对路径
  • path.join([…path]) :使用平台特定的分隔符作为定界符将所有给定的 path 片段连接在一起,然后规范化生成的路径
  • path.parse(path) :返回一个对象,其属性表示 path 的重要元素。 尾部的目录分隔符将被忽略
  • path.format(path) :从对象返回路径字符串。 与 path.parse() 相反。
    • 如果提供了 pathObject.dir,则忽略 pathObject.root
    • 如果 pathObject.base 存在,则忽略 pathObject.extpathObject.name
  /* {
    root: '/',
    dir: '/foo/bare/styd',
    base: 'query.txt',
    ext: '.txt',
    name: 'query'
  } */
  console.log(path.parse('/foo/bare/styd/query.txt'));//返回上述一个对象
  let pp = {
     
      root: '/',
      dir: '/foo/bare/styd',
      base: 'query.txt',
      ext: '.txt',
      name: 'query'
  }
  console.log("format==",path.format(pp));//format== /foo/bare/styd\query.txt

  console.log(path.relative('aaa','bbb','ccc'));//..\bbb

  console.log(path.resolve('/aaa','bar','bb/ffb','ccc','..'));//D:\aaa\bar\bb\ffb

 console.log(path.join('/foo','bar','/baz/asdf','qunx','..'));//\foo\bar\baz\asdf
	path.extname('.index');
	// 返回: ''
	
	path.extname('.index.md');
	// 返回: '.md'

3.3file

  • 文件操作

    • 查看文件状态

      • fs.stat( path [, options], calback ) : 查看文件状态
        • 方法
          • stat.isDirectory() : 判断是否是目录
          • stat.isFile() : 判断是否是文件
        • 属性
          • atime : 文件访问时间
          • ctime : 文件的状态信息发生变化的时间(比如文件的权限)
          • mtime : 文件数据发生变化的时间
          • birthtime : 文件创建的时间
    • 读文件操作

      • fs.readFile( path [, options], calback ) : 读文件
        • 文件描述符
    • 写文件操作

      • fs.writeFile( file, data [, options], calback ) : 写文件
      • 大文件操作
  • 目录操作

    • fs.mkdir(path [, options], callback) : 创建文件
    • fs.readdir(path [, options], callback) : 读取目录
    • fs.rmdir(path [, options], callback) : 删除目录
fs.stat('./01.txt',(err,stats) => {
     
    if(err) {
     

    }else{
     
        console.log("stats---->",stats)
    }
})
//拼接读取  编码格式写到第二个参数
fs.readFile(path.join(__dirname, '01.txt'),'utf8',(err, data) => {
     
    // if(err){
     
    //     console.log('err --->',err);
    //     console.log("读取文件出错");
    //     return;
    // }

    if(err){
     return;}

    console.log('data --->',data);
    console.log('data --->',data.toString);
});
fs.writeFile(path.join(__dirname,'02.txt'),'呵呵呵',(err) => {
     
    if(err){
     
        console.log('写入失败');
    }else{
     
        console.log('写入成功');
    }
})

四、Buffer(缓冲区)

Buffer 对象是node处理二进制数据的一个接口

  • 实例化
    • Buffer.from(array)
    • Buffer.alloc(size)
let arr = ['61','62','63','64','65','66','67','68'];
var a = parseInt(arr[0],16).toString(2);//转换为二进制
//console.log(a);//1100001

const buf2 = Buffer.from('abcd','utf8');
const buf3 = Buffer.from('哈哈','utf8');

console.log('buf2 ---->',buf2.toString());//abcd

let buf4 = Buffer.alloc(5);//buf4长度为5字节
buf4.write('abcdefg',2,5);//2表示跳过2个字节,则只有3个,因此为abc
console.log(buf4.toString());//abc
  • 功能方法
    • Buffer.isEncoding() 判断是否支持该编码
    • Buffer.isBuffer() 判断是否为 Buffer 对象
    • Buffer.byteLength() 返回指定 Buffer 的字节长度。 默认 utf8
    • Buffer.concat() 将一组 Buffer 对象合并为一个 Buffer 对象
var buffer1 = Buffer.from(('菜鸟教程'));
var buffer2 = Buffer.from(('www.baodu.com'));
var buffer3 = Buffer.concat([buffer1, buffer2]);
console.log("buffer3内容:"+buffer3.toString())
  • 实例方法
    • write()
  - slice()
  • toString()

五、初步实现服务器

5.1第一种方式

 const http = require('http');
 let server = http.createServer();
 /* 创建服务器*/`在这里插入代码片`
 server.on('request',(request,response) => {
     
    response.write('hello node');
    /* 结束 */
    response.end();
 });
 /* 服务器监听 */
 server.listen(8080,() => {
     
     console.log('server is running...');
 })

5.2第二种方式

/* 第二种方式 */
let server = http.createServer((request,response) => {
     
    response.writeHead(200,{
     "Content-Type":"text/plain;charset=utf-8"});
    if(request.url === '/favicon.ico'){
     
        response.writeHead(200, {
     "Conten-Type":"text/plain"});
        response.end();
    }else if(request.url === '/aaa'){
     
        // console.log('request.url ---->',request.url);
        response.end("请求的路径为:"+request.url);
    }else if(request.url === '/bbb'){
     
        // console.log('request.url ---->',request.url);
        response.end("请求的路径为:"+request.url);
    }else if(request.url === '/index.html'){
     
        // console.log('request.url ---->',request.url);
        response.end("请求的路径为:"+request.url);
    }else{
     
        // console.log('request.url ---->',request.url);
        response.end("404--因为没找到");
    }
});
server.listen(8080,() => {
     
    console.log("server is running...\n------");
})

五、静态服务器实战

//读模块
const fs = require('fs');
//处理路径
const path = require('path');
//处理格式
let mime = require('./public/mime.json')
/* 导出 */
module.exports = (req,res,rootPath) => {
     
    //读文件
    fs.readFile(path.join(rootPath,req.url),(err, data) => {
     
        if(err){
     
            console.log("出错啦!!!");
            res.writeHead(200,{
     "Content-Type":"text/plain;charset=utf-8"})
            res.end('500 服务器开小差啦!!!程序员小哥正在维护...');
        }else{
     
            let mimeType = "text/plain";
            /* extname返回文件扩展名 */
            let ext = path.extname(req.url);
            console.log("ext ---->",ext);
            //将文件的扩展名  传给mime
            mimeType = mime[ext];
            if(mimeType.startsWith('text')){
     
                mimeType = mimeType+';charset=utf8';
            }
            /* 设置请求头 */
            res.writeHead(200,'ok!!!',{
     'Content-Type': mimeType});
            // res.writeHead(200,'ok!!!',{'Content-Type': 'text/html;charset=utf8'})
            res.write(data);
            res.end();
        }
    })
}
const http = require('http');
const path = require('path');
//引入服务器
let staticServer = require('./02-staticservice')
//创建服务器
http.createServer((req,res) => {
     
    //静态服务
    staticServer(req,res,path.join(__dirname,'WWW'))
}).listen(8080,() => {
     
    console.log('running...');
})

六、get/post数据处理

6.1、处理get传输的数据

localhost:8080/aaa/bbb?a=111&b=222

const http = require('http');
const url = require('url');

/* 创建服务 */
http.createServer((req, res) => {
     
    if(req.url==='/favicon.ico'){
     
        res.end();
        return;
    }
    console.log('---->>',"有人访问了");
    //get 数据处理
    let {
     query:{
     c,d}} = url.parse(req.url,true);
    console.log('c -->', c);
    console.log('d -->', d);

}).listen(8080,() => {
     
    console.log('running....');
})

6.2、处理post传输的数据

前台代码

	<form method="post" action="http://localhost:8080">
        <div>
            <input type="text" name="aaa">
        </div>
        <div>
            <input type="text" name="bbb">
        </div>
        <button type="submit">提交</button>
    </form>

数据处理

const http = require('http');
const querystring  = require('querystring');
http.createServer((req,res) => {
     
    if(req.url === '/favicon.ico'){
     
        res.end();
        return;
    }
    console.log('req.url====>>>',req.url);
    let str = "";
    //post 数据处理  数据会存在body中
    //事件
    req.on('data', chunk => {
     
        str+= chunk;
    })
    req.on('end',() => {
     
        console.log('接收完毕');
        let obj = querystring.parse(str);

        console.log('obj --->',obj);
    });
}).listen(8080,() => {
     
    console.log('running....');
})

6.3、同时处理get、post传输的数据

前台代码:

	<form method="post" action="http://localhost:8080/index?c=111&d=222">
        <div>
            <input type="text" name="aaa">
        </div>
        <div>
            <input type="text" name="bbb">
        </div>
        <button type="submit">提交</button>
    </form>

数据处理

//创建个服务器
const http = require('http');
const url = require('url');
const querystring = require('querystring');

/* 创建服务 */
http.createServer((req, res) => {
     
    if(req.url==='/favicon.ico'){
     
        res.end();
        return;
    }
    console.log('---->>',"有人访问了");

    //get 数据处理
    let {
     query:{
     c,d}} = url.parse(req.url,true);
    console.log('c -->', c);
    console.log('d -->', d);

    let str = "";
    //post 数据处理
    req.on('data', chunk => {
     
        str+= chunk;
    })
    req.on('end',() => {
     
        console.log('接收完毕');
        let {
     aaa,bbb} = querystring.parse(str);

        console.log('aaa --->',aaa);
        console.log('bbb --->',bbb);
    });
    res.end('{"code":"0"}')
}).listen(8080,() => {
     
    console.log('running....');
})

6.4、登录注册小案例

(一)index.js

//创建个服务器
const http = require('http');
const url = require('url');
const path = require('path');
const querystring = require('querystring');
//引入
let staticService = require('./02-staticservice');
let user = {
     };
/* 创建服务 */
http.createServer((req, res) => {
     
    if(req.url==='/favicon.ico'){
     
        res.end();
        return;
    } 
    //处理get数据
    let {
     pathname,query:{
     name,pass}} = url.parse(req.url,true);
    
    //处理post数据
    let data = '';
    req.on('data',chunk => {
     
        data += chunk;
    });
    req.on('end',() => {
     
        /* 登录 */
        if(pathname === '/login'){
     
            res.writeHead(200, {
     "Content-Type": "text/plain;charset=utf8"});
            if(user[name] && user[name] === pass){
     
                res.end('{"code":1,"msg":"登录成功"}');
            }else{
     
                res.end('{"code":1,"msg":"用户名或密码错误"}');
            }
        }
        /* 注册 */
        else if(req.url === '/register'){
     
            // console.log(' ===>','register');
            //处理乱码
            res.writeHead(200, {
     "Content-Type": "text/plain;charset=utf8"});
            let {
     name:post_name,pass:post_pass} = querystring.parse(data);
            if(!post_name){
     
                res.end('{"code":1,"msg":"请输入用户名"}');
            }else if(!post_pass){
     
                res.end('{"code":1,"msg":"请输入密码"}');
            }else if(user[post_name]){
     
                res.end('{"code":1,"msg":"用户名已注册"}');
            }else{
     
                res.end('{"code":0,"msg":"注册成功"}');
                //把数据存起来
                user[post_name] = post_pass;
            }
        }else{
     
            staticService(req, res,path.join(__dirname,'static'));
        }
        console.log('user--->',user);
    })

    // res.end('{"code":0}');
}).listen(8080,() => {
     
    console.log('running...')
})

(二)index.html

//创建个服务器
const http = require('http');
const url = require('url');
const path = require('path');
const querystring = require('querystring');
//引入
let staticService = require('./02-staticservice');
let user = {
     };
/* 创建服务 */
http.createServer((req, res) => {
     
    if(req.url==='/favicon.ico'){
     
        res.end();
        return;
    } 
    //处理get数据
    let {
     pathname,query:{
     name,pass}} = url.parse(req.url,true);
    
    //处理post数据
    let data = '';
    req.on('data',chunk => {
     
        data += chunk;
    });
    req.on('end',() => {
     
        /* 登录 */
        if(pathname === '/login'){
     
            res.writeHead(200, {
     "Content-Type": "text/plain;charset=utf8"});
            if(user[name] && user[name] === pass){
     
                res.end('{"code":1,"msg":"登录成功"}');
            }else{
     
                res.end('{"code":1,"msg":"用户名或密码错误"}');
            }
        }
        /* 注册 */
        else if(req.url === '/register'){
     
            // console.log(' ===>','register');
            //处理乱码
            res.writeHead(200, {
     "Content-Type": "text/plain;charset=utf8"});
            let {
     name:post_name,pass:post_pass} = querystring.parse(data);
            if(!post_name){
     
                res.end('{"code":1,"msg":"请输入用户名"}');
            }else if(!post_pass){
     
                res.end('{"code":1,"msg":"请输入密码"}');
            }else if(user[post_name]){
     
                res.end('{"code":1,"msg":"用户名已注册"}');
            }else{
     
                res.end('{"code":0,"msg":"注册成功"}');
                //把数据存起来
                user[post_name] = post_pass;
            }
        }else{
     
            staticService(req, res,path.join(__dirname,'static'));
        }
        console.log('user--->',user);
    })

    // res.end('{"code":0}');
}).listen(8080,() => {
     
    console.log('running...')
})

(三)02-staticservice.js

const fs = require('fs');
const path = require('path');
let mime = require('./public/mime.json')

module.exports = ( req, res, rootPath ) => {
     
    fs.readFile(path.join(rootPath, req.url), ( err, data ) => {
     
        if(err){
     
            console.log('出错啦!!!')
            res.writeHead(200, {
     "Content-Type": "text/plain; charset=utf8"})
            // res.end('500 服务器开小差啦!! 程序员小哥正在···')
            res.end('404 请求资源不存在')
        }else{
     
            // req.url  -->  /index.html
            let mimeType = "text/plain";

            let ext = path.extname(req.url);
            // console.log('ext ---->', ext);
            mimeType = mime[ext];

            if(mimeType.startsWith('text')){
     
                mimeType = mimeType+'; charset=utf8';
            }
            res.writeHead(200, 'ok!!!', {
     "Content-Type": mimeType });
            res.write(data);
            res.end()
        }
    })
}

node学习(二)

你可能感兴趣的:(Node,nodejs)