关于NodeJS

1. NodeJS

  1. NodeJS(node.js)是JavaScript运行环境.
  2. 安装成功后可以直接通过浏览器访问JavaScript代码。
  3. 作用:typeScript;让 JavaScript 成为与PHP、Python 等平起平坐的语言;前段脱离后端,直接通过JS写项目。
  4. 下载的地址:
    1. 官 网:nodejs.org
    2. 中文网址:nodejs.cn
    3. 学习社区:cnodejs.org
  5. 相关工具:
    1. nvm工具:实现nodejs任意版本切换
    2. npm工具:下载nodejs所需模块(工具库)

2. JS的安装和使用

  1. 根据电脑配置在官网下载安装包,安装过程中唯一需要注意的就是选择安装目录

  2. 安装完毕之后进行测试,在cmd中(尽量使用以管理员的身份运行)输入node -v显示版本号

nodejs01.png
  1. 在工作路径下可直接调用js输出结果
nodejs02.png

3. 模块系统

  1. 使用NodeJS编写应用程序主要使用

    1. ECMAScript语法:变量、判断、循环等(JS三大组成部分:ECMA/DOM/BOM)
    2. 内置/核心模块:http服务、fs文件操作、url路径、path路径处理、os操作系统
  2. CommonJS模块规范

    1. 一个文件就是一个模块
    2. 通过require来加载模块
    3. 通过exports和modul.exports来导出模块中的成员(声明模块中哪些功能可以使用)
  3. 自定义node.js模块

//声明模块
//写法1
exports.属性/方法名 = 功能
//写法2
module.exports.属性/方法名 = 变量名;

//使用:先引入再调用
var 对象 = require(‘路径及文件名’);
//对象.属性或方法名;

举例:创建a.js和b.js文件,在b.js引入a.js模块

//a.js内容
    function add(){
        console.log('this is add');
    }
    function edit(){
        console.log('this is edit');
    }
    function del(){
        console.log('this is del');
    }
    // 使用exports进行导出
    exports.add = add;
    exports.edit = edit;
    exports.del = del;
    exports.say = 'hello';

//b.js的内容
    //引用a
    var b=require('./a');
    //将say的值改为hello
    b.say = 'world';
    console.log(b);
  1. exports和module.exports的区别

    上述a.js的导出可写为:

// 使用exports进行导出
    module.exports.add = add;
    module.exports.edit = edit;
    module.exports.del = del;
    exports.say = 'hello';

区别:exports和module.exports是同一个对象;但exports仅仅是module.exports的一个地址引用;nodejs只会导出module.exports的指向,如果exports指向变了,那就仅仅是exports不在指向module.exports,于是不会再被导出。

4. npm工具使用

  1. npm是一个命令行工具,是英文node package manager的缩写,下载node所需第三方模块;安装NodeJS自带npm所以不用重新安装,直接使用。

  2. npm的命令(都是在cmd中运行)

    1. 查看已安装的:npm list
    2. 安装:npm install [模块 或 模块@版本号] [安装可选参数]
    3. 卸载:npm uninstall [模块]
  3. 安装可选参数

    1. --save 记录生产环境所需模块(默认)
    2. --save-dev 块版本信息保存到devDependencies(开发环境)
    3. -g 全局命令;该模块可在命令行(cmd中)运行(global)
  4. 代码的运行环境:生产和开发

    1. 生产:项目上线正常运行使用的环境;生产环境的包如果遇到了代码错误,只会终止代码执行,不会报明确的错误。
    2. 开发:写代码实现功能时,使用的环境;开发环境下,代码错误就会明确的指出错误的原因和地址。

5. npm安装mime模块

MIME是一个规则,类型text/html - .html文件、image/png- png文件等;安装mime模块,则该模块用户可判断文件mime类型

  1. 运行cmd到所需要的工作目录,使用如下代码进行初始化

    npm init -y

    会在工作目录下生成package.json项目描述文件

// name - 包名.
// version - 包的版本号。
// description - 包的描述。
// homepage - 包的官网URL。
// author - 包的作者,它的值是你在https://npmjs.org网站的有效账户名,遵循“账户名<邮件>”的规则,例如:zhangsan <zhangsan@163.com>。
// contributors - 包的其他贡献者。
// dependencies / devDependencies - 生产/开发环境依赖包列表。它们将会被安装在 node_module 目录下。
// repository - 包代码的Repo信息,包括type和URL,type可以是git或svn,URL则是包的Repo地址。
// main - main 字段指定了程序的主入口文件,require('moduleName') 就会加载这个文件。这个字段的默认值是模块根目录下面的 // index.js
// keywords - 关键字
  1. 使用如下代码安装mime

    npm install mime

  2. 创建mime.js测试,获取文件的类型——文档:https://www.npmjs.com/package/mime

    //引入mime
    var mime = require('mime');
    //定义文件
    var file = 'cc.png';
    //获取图片的后缀
    var imgType = mime.getType(file);
    console.log(imgType);
    //获取图片所属mime类型
    console.log(mime.getExtension(imgType));
  1. 报错情况

    使用-g安装为全局命令,否则在cmd命令行里直接运行 mime aa.jpg 会报错

    需要使用uninstall来写在mime包,加上-g后重新安装

6. NPM源管理

  1. 安装nrm命令——npm install nrm -g
  2. 使用命令查看可用服务器——nrm ls
  3. 使用命令更换服务器——nrm use [服务器名字]


    nodejs03.png

7. npm自定义命令

当后期项目较大时可以用一条命令进行启动;仅需要修改package.json中的scripts进行启动;
//package文件中会有如下一个模块
//通过npm命令行启动mime.js,相当于配置了快捷方式
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1",
    "start":"node mime.js"
  },
因此,在cmd中使用代码:npm run start即可运行,start 命令就是package.json启动项目的命令;

其中的run:npm run是npm run-script的简写,顾名思义就是执行脚本。执行的脚本配置在package.json中的scripts对象;

8. nodemon自动重启服务

我们发现,每次修改js代码都得重新启动服务才能读取变化,非常的不方便,因此可通过nodemon检测文件修改自动重启;
  1. 安装nodemon——npm install nodemon --save-dev -g

    指定安装开发环境且配置为全局

  2. 通过nodemon启动服务 -> 测试

    例如在cmd中输入nodemon test.js

9. http模块

Node中提供了http模块,其中封装了高效的http服务器和http客户端 http.server是一个基于事件的HTTP服务器,内部是由c++实现的,接口由JavaScript封装 http.request是一个HTTP客户端工具。用户向服务器发送数据。

手册:https://www.nodeapp.cn/http.html#http_http_createserver_requestlistener

  1. http模块中常见的方法

    1. createServer() 返回新建的http.Server实例。

    2. server.on('request',function(){}) 监听客户请求

    3. server.listen() 启动 HTTP 服务器监听连接.

    4. reponse.write() 给客户端响应数据

    5. response.end() 结束响应

  2. 创建http服务器:

    1. 新建http.js文件,写入服务器代码,监听客户请求
// 1 引入http模块
        var http = require('http');
        // 2使用createServer创建一个服务器
        var server = http.createServer();
        // 3 监听用户的请求,凡是xxx事件,都可以使用on绑定
        server.on('request',function(request,response){
         console.log('客户的请求收到了!');
        });
        // 4 启动服务器
        server.listen(8080,function(){
         console.log('服务器已经启动,可以访问8080');
        });
  1. 监听到客户请求之后进行响应

    // 1 引入http模块
    var http = require('http');
    // 2使用createServer创建一个服务器
    var server = http.createServer();
    // 3 监听用户的请求,凡是xxx事件,都可以使用on绑定
    server.on('request',function(request,response){
        // 如果地址显示是 \ 则表示根目录
        console.log('客户的请求来自'+request.url);
        // 5 给客户返回数据
         response.setHeader('Content-Type','text/html;charset=UTF-8');  // 防止中文乱码
         response.write('Hello');
         response.write('I have a dream');
         response.end();
    });
    // 4 启动服务器
    server.listen(8080,function(){
        console.log('服务器已经启动,可以访问8080');
    });
    
  2. 判断用户登录的是首页还是登录页,响应出不同的数据

    // 1 引入http模块
    var http = require('http');
    // 2使用createServer创建一个服务器
    var server = http.createServer();
    // 3 监听用户的请求,凡是xxx事件,都可以使用on绑定
    server.on('request',function(request,response){
        // 根据获取的url判断用户当前访问的页面
        var url = request.url;
        var str = '';
        if(url=='/'){
            str = '你访问的是首页';
        }else if(url=='/login'){
            str = '访问的是登录页';
        }else{
            str = '来自星球的页面';
        }
        // 5 给客户返回数据
         response.setHeader('Content-Type','text/html;charset=UTF-8'); //防止中文乱码
         response.write(str);
         response.end();
    
    });
    //4  启动服务器
    server.listen(8080,function(){
        console.log('服务器已经启动,可以访问8080');
    });
    
  3. 使用 http.createServer() 方法创建服务器

    var http = require('http');
    http.createServer(function (request, response) {
        // 发送 HTTP 头部 
        // HTTP 状态值: 200 : OK
        // 内容类型: text/plain
        response.writeHead(200, {'Content-Type': 'text/html;charset=UTF-8'});
        // 发送响应数据 "Hello World"
        response.end('Hello World\n');
    }).listen(8889);
    
  4. request中的更多属性

    console.log(request.headers);        //获取请求头信息(对象)
    
    console.log(request.rawHeaders);     //获取请求头信息(数组)
    
    console.log(request.httpVersion);    //获取HTTP版本
    
    console.log(request.method);     //获取请求方法
    
    console.log(request.url);            //获取请求路径(注:不含网址)
    
  5. response中的更多属性

    //方法1:分开写
    response.statusCode = 404;
    response.statusMessage = 'Not Found2';
    response.setHeader('Content-Type', 'text/html; charset=utf-8')
    response.write('打印response数据');
    response.end();
    //方法2:
    response.writeHeader(404,'Not Found',{'Content-Type':'text/html;charset=utf8'});
    

10. 路由搭建

  1. 路由的使用:url.parse(urlStr, [parseQueryString], [slashesDenoteHost])
    1. url.pathname 获取及设置URL的路径(path)部分;
    2. parse() 将一个URL字符串转换成对象并返回,用于地址解析;
var src = "http://127.0.0.1:8888/two?a=3&b=4";
var url  = require('url');
console.log(url.parse(src));
// 包含如下:
Url {
      protocol: 'http:',
      slashes: true,
      auth: null,       //URL的身份认证信息
      host: '127.0.0.1:8888',
      port: '8888',
      hostname: '127.0.0.1',
      hash: null,
      search: '?a=3&b=4',   //URL的查询字符串部分,包括前导的问号
      query: 'a=3&b=4',     //要么是查询字符串中的参数部分,要么是含有查询字符串参数和值的解析后的对象
      pathname: '/two',     //URL的路径部分(包括最初的斜线,如果存在的话)
      path: '/two?a=3&b=4', 
      href: 'http://127.0.0.1:8888/two?a=3&b=4'
 }

案例:

  1. 用户点击one时,跳转到one页面,点击two跳转到two页面
  2. 将服务器已提供的方法的,分别保存起来
  3. 开启服务器,进行监听.获取路径中用户访问的地址.
  4. 将访问路径和已有方法进行比对,如果有则返回响应内容

第一步:编写method.js提供one方法和two方法

//method.js 文件
//分别形成完整的页面结构
function one(){
    var body = '<html>' + 
    '<head>' +
    '<meta http-equiv-"Content-Type" content="text/html;charset=UTF-8"/>' +
    '</head>' +
    '<body>' +
    '<a href="/two">我是one页面,点击跳到TWO</a>' +
    '</body>'+
    '</html>';
   return body;
}

function two(){
    var body = '<html>' + 
    '<head>' +
    '<meta http-equiv-"Content-Type" content="text/html;charset=UTF-8"/>' +
    '</head>' +
    '<body>' +
    '<a href="/one">我是TWO页面,点击跳到ONE</a>' +
    '</body>'+
    '</html>';
    return body;
}
//导出方法
exports.one = one;
exports.two = two;

第二步:创建server.js 根据不同的路由,显示不同页面

//server.js文件
var http = require('http');
var url = require('url');
//引用第一步写的js文件
var method = require('./method');
function startServer(){
    //使用createServer创建一个服务器
    var server = http.createServer();
    var body ='';
    //监听
    server.on('request',function(request,response){
        var pathName = url.parse(request.url).pathname;
        //console.log(pathName);
        if(pathName=='/one' || pathName=='/'){
             body = method.one();
        }
        if(pathName=='/two'){
              body = method.two();
        }
      //  response.writeHead(200,{"Content-Type":"text/html"});
        response.setHeader('Content-Type','text/html;charset=UTF-8');
        //打印body
        response.write(body);
        response.end();
    });
    //开启服务器,设置端口号
    server.listen(8888);
}
startServer();
  1. 参数的获取 GET&POST
//get方式

let {pathname,query} = url.parse(req.url);
//输出: query.username
//post方式

// 1 引入http模块
var http = require('http');
var url = require('url');
var querystring = require('querystring');
//2 创建服务器
var server = http.createServer();
//3 监听所有的请求
server.on('request',function(request,reponse){
      //console.log('请求收到了');
      // get参数的接受
      // var {pathname,query} = url.parse(request.url);
      // console.log(pathname,query)
     
      // post参数的接收
      let arr = []; 
      // 开始接收参数
      request.on('data',buffer=>{ 
             arr.push(buffer);
            }); 
      // end 表示参数接收完成
      request.on('end',()=>{ 
        let buf = Buffer.concat(arr);
        // parse这个方法是将一个字符串反序列化为一个对象。
        let post = querystring.parse(buf.toString());
        console.log(post);
      });
})
// 4 开启服务器,制定端口
server.listen(8888,function(){
    console.log('服务器8888 开启了')
});

post传递的数据一般比较大,分多次传递,监听data事件,每当一段数据到达时就触发一次,将数组添加到arr数组里。end事件是当所有数据接收完成时触发的。

结尾:
nodeJS很重要,后续会继续总结分享,未完待续~
仅根据个人学习后的理解整理如上知识点,如有错误,请不吝赐教~

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 217,734评论 6 505
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,931评论 3 394
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 164,133评论 0 354
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,532评论 1 293
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,585评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,462评论 1 302
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,262评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,153评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,587评论 1 314
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,792评论 3 336
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,919评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,635评论 5 345
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,237评论 3 329
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,855评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,983评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,048评论 3 370
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,864评论 2 354

推荐阅读更多精彩内容