牛!总结Node.js学习干货

1. 初识Node.js

Node.js是什么

Node.js不是一门语言
Node.js不是库(library)、不是框架(frame)
==Node.js是一个JavaScript运行环境==
<u>简单点来讲就是Node.js可以解析和执行JavaScript代码</u>
==以前只有浏览器可以解析和执行JavaScript代码==
也就是说现在的JavaScript可以完全脱落浏览器来运行,一切都归功于:Node.js
构建于chrome的v8引擎之上
Node.js中的JavaScript
没有BOMDOM
有ECMAScript
在Node这个JavaScript执行环境中为JavaScript提供了一些服务器级别的操作API
1:文件的读写:
2:网络服务的构建
3:网络通信
4:http服务器:等处理(相当于开发web服务器,学习对应的api即可)
event-driven 事件驱动
non-blocking I/O model 非阻塞IO模型(异步)
lightweight and efficient. 轻量和高效
随着课程慢慢学习会明白事件驱动、非阻塞IO模型
==NodeJS以事件驱动著名,通过异步的编程达到高吞吐量高性能。==

达到目标

模块化编程

RequireJS
SeaJS
css中可以使用@import('文件路径')来实现引入外部文件
以前认知的js智能通过script标签来加载
在Node中可以像@import一样来引用加载JavaScript脚本文件

异步编程

回调函数
Promise
async
generator

Express web开发框架

node练习

**node只有js文件,代码一般为 .js文件**
1:创建编写js文件:
2:打开终端(命令行),定位到脚本文件所属目录
3:输入node 文件名执行对应的文件,显示结果
==注意:文件名不能使用node,最好也不要使用中文==

解析执行JavaScript

读写文件

使用fs模块

var fs = require('fs');

读取文件

fs.readFile('路径', '可选编码', function (error, data) {});//具体查看代码

readFile方法的第二个参数为可选参数,规定解析文件的编码,可选择utf-8编码,让他以网页原文件的形式读取,不是二进制数据

写文件

fs.writeFile();

Node.js中常常使用回调函数作为参数,因为是异步的==

HTTP
详见代码。
服务器和web页面一般使用字符串进行通信,因此json的传递需要转化为字符串
Ctrl+c可以关闭服务器(bash和cmd一样)
在浏览器查看http请求中,有一个/favicon.ico路径,该请求是浏览器的默认行为,目的是请求网页的网站头像
响应内容只能是字符串或二进制数据(Buffer)。对象、数字、数组、布尔值都不行,因此response.end()方法能够响应字符串和二进制数据

核心模块

Node为JavaScript提供了很多服务器级别的API,这些API绝大多数都被包装到了一个具名的核心模块中了。

例如文件操作的fs核心模块,http服务构建http模块,path路劲操作模块、os操作系统信息模块。

只要提到一个核心模块,就要想到引入该模块。使用require[1]
var fs = require('fs');
var http = require('http');
==模块的好处:可以完全避免变量命名冲突污染的问题==

但是模块之间的通信需要使用模块中的exports对象

==使用的所有文件操作的API都是异步的,即核心模块fs的方法。执行顺序可能要放到其他执行过程的后边执行==

用户自定义模块

**Node.js不能同时执行多个js文件,需要使用模块化编程**

1:模块化相当于同一个文件中的script标签:
2==模块的功能要单一==

**require**
1:require是一个方法,作用是用来加载模块的:
2:在Node中,模块有三种
  具名的核心模块,例如fs、http
  用户自己编写的模块(就是一个js文件),可以使用require方法加载。==相对路径必须加./==,否则会报错,因为会将模块认定为一个核心模块
  
在node中没有全局作用域,只有==模块作用域==,相当于两个script标签。require方法加载时可以省略后缀名的。

1:推荐使用省略后缀名的写法:
2:既然是模块作用域,如何让模块与模块之间通信

**require方法有两个作用:**
1:加载文件模块并执行里面的代码:
2:拿到被加载文件模块导出的接口对象

**​ 每个文件模块中都提供了一个对象:exports**

​ exports默认是一个空对象,是require方法的返回值

exports
1:exports用来实现不同模块之间的通信:
2==每个模块中都提供了一个exports对象,默认是一个空对象==
3:该对象类似于原型链中的prototype对象,能够向对象中添加数据,另一个模块可以通过require方法返回的exports对象使用这些添加的数据

web服务器开发

1:计算机中只有一个物理网卡,而且同一个局域网中,网卡的地址必须是唯一的。
2:网卡是通过唯一的ip地址来进行定位的
3:ip地址用来定位计算机
4:端口号用来定位具体的应用程序(所有需要联网通信的软件都必须具有端口号),通信的软件占用
5:端口号的范围从0~65536之间
6:在计算机中有一些默认的端口号,最好不要去占用
7:例如http服务的80
8:可以同时开启多个服务,但一定要确保不同服务占用的端口号不一致。同一个端口号只能被一个程序占用
9:目前发现,node的网络编程主要是通过request和response两个对象来实现的。一般就是监听request事件来获取客户端和服务端的数据。
10:request代表着客户端的信息,response代表着服务器的信息
11:开启服务器流程

var http = require('http')

//1.  创建server
var server = http.createServer()

//2.  监听Server的request请求事件,设置请求处理函数
        // 请求
            // 处理
        // 响应
        // 一个请求对应一个响应,如果一个请求过程中,已经结束响应了,则不能重发发送响应。
        // 没有请求就没有响应

server.on('request', function (req, res) {
    console.log(req.url)
})

// 3.绑定端口号,启动服务

server.listen(3000, function () {
    console.log('server running');
})

目录斜杠问题

1:字符串目录一般采用斜杠/,也可以使用\,\反斜杠的作用是用来转义:
2:Windows的目录采用了\来显示目录,这点与字符串和网址的url相反

url模块

1:url模块能够用于 URL 处理与解析:
2:url.parse()方法能够解析请求网址,返回一个包含各个请求数据的对象。记住第二个参数设置为true
3:该方法返回的路劲也为端口号后面的路径:
4:网页中的路径都是url路径,不是文件路径

CommonJs模块规范

在Node中的js还有一个重要的概念:模块系统:
1:模块作用域
2:使用require方法用来加载模块
3:使用exports接口对象用来导出模块中的成员

module.exports = 'hello'//这样另一个模块加载这个模块就会返回'hello',而不是exports对象

加载 require

var 自定义变量名 = require('模块')

导出exports
1:Node中是模块作用域,默认文件中所有的成员只在当前文件模块中有效
2:对于希望可以被其他模块访问的成员,我们就需要把这些公开的成员都挂载到exports接口对象中

exports.a = 123
exports.b = {
    foo : 123
}
module.exports = 'hello'
module.exports = function(){//后者会覆盖前者
    
}

原理解析
1:可以认为在node中,没一个模块都有一个自己的module对象
2:module对象中,有一个成员叫:exports成员也是一个对象
3:也就是说需要对外导出成员,只需要把导出的成员挂载到module.exports对象中

var module = {
    exports : {
        
    }
}
//谁require这个模块,就会得到 module.exports
//为了简化操作,在模块中还有一句代码
var exports = module.exports  //exports和module.exports挂载是一样的。这行代码应该是在第一行
console.log(exports === module.exports)//结果为true
//默认在代码的最后又一句:
return module.exports
//一定要记住return的是module.exports,不能通过直接修改exports影响返回的对象,因此导出单个成员需要修改module.exports对象

require方法加载规则
1:优先从缓存加载
2:不会重复加载相同的模块
3:可以拿到其中的接口对象,不会重复执行模块中的代码
4:这样做是为了避免重复加载模块,提高加载效率
5:require的参数为模块标识
6:加载时要判断模块标识

Express

原生的http在某些方面表现不足以应对我们的开发需求,所以我们就需要使用框架来加快我们的开发效率,框架的目的就是提高效率,让我们的代码更高度统一。

1:注意 express 也可以使用原生的方法
2:Express 是一个简洁而灵活的 node.js Web应用框架, 提供了一系列强大特性帮助你创建各种 Web 应用,和丰富的 HTTP 工具。使用 Express 可以快速地搭建一个完整功能的网站。
3:在Node中,有很多的web开发框架,我们这里以学习express为主。

//先建一个app.js
// 安装依赖
// 初始化应用
// 引包开发

var express = require('express')

// 2.创建你的服务器应用程序
// 也就是原来的 http.createServer

var app = express()   //相当于原来的server
//当服务器收到get请求/的时候,执行回调处理函数。必须为get请求
app.get('/', function (req, res) {
    res.send('hello world')
})
//不需要一个一个再判断了
app.get('/about', function (req, res) {
    res.send('你好') //此处的编码问题框架已经帮我们处理好了,不需要res.setHeader()
})
//相当于server.listen
app.listen(3000, function () {
    console.log('app is running at port 3000.')
})

express的request对象

//req对象中直接包含了 原生 url 模块中返回的方法
req.query   //返回参数对象

express公开指定的目录(处理静态资源)

// 公开指定目录
//只要这样做了,就可以直接通过 /public/xx 的方式访问 public 目录中的所有资源了
app.use('/public/', express.static('./public/'))  //相当于拼接的'. + 路径'

1:不公开目录默认找不到路径处理。
2:上述代码公开的是public文件夹下的文件,因此次用‘/public/’的形式,也可以使用/public,它只是在检测url是否以你定义的开头
3:浏览器的访问路径只有在端口号后没有’/'的时候补一个‘/’,浏览器在文件路径后面补一个‘/’,其他的路径都是在浏览器地址栏看到的路径,没有区别。

总结:
1:get方法是用来判断访问路径,作出处理的
2:use方法是用来开发静态资源的。
3:浏览器路径确认是文件,会在后面自动拼接一个/
4:在Express中开放资源就是一个API的事儿;模板引擎在Express中也是一个API的事儿

express 基本路由(router)

路由(routing)是指分组从源到目的地时,决定端到端路径的网络范围的进程。

1:路由其实就是一张表。我们已经了解了 HTTP 请求的基本应用,而路由决定了由谁(指定脚本)去响应客户端请求。
2:这个表里面有具体的映射关系
3:当请求’/’,执行什么语句,分配什么
4:app.get()方法会返回app对象,可以链式编程,继续执行get方法
5:express 中的get方法就相当于一个路由,以什么路径执行的时候,执行对应的处理函数,就是一个路由处理
6:千万不要纠结端口后面的请求url是否加/开头,不加也可以

//当以 GET方法请求 / 的时候,执行对应的处理函数
app.get('/', function (req, res) {
    res.send('hello')
})
//当以 POST 方法请求 / 的时候,执行对应的处理函数
app.post('/', function (req, res) {
    res.send('hello')
})

express静态服务

1:当以/public/开头的时候,添加.去./public/目录中寻找对应的资源

app.use('/public/', express.static('./public/'))

2:当省略第一个参数的时候,则可以通过省略 /public 的方式来访问。直接写该目录下的资源路径即可,例如public目录下的index.html,url为 127.0.0.1:3000/inde.html

app.use(express.static('./public/'))

3:当指定第一个参数的时候,必须是/a/为开头取代 /public/ 访问public中的资源,是为了方便指定定制访问路径。例:1207.0.0.1:3000/a/index.html 才能访问如下的开放目录。

app.use('/a/', express.static('./public/'))

在express中配置使用art-template模板引擎

npm install --save art-template
npm install --save express-art-template

配置:

app.engine('art', require('express-art-template'))
// 第一个参数标识,当前以 .art 结尾的文件的时候,使用art-template模板引擎
// 也可以把第一个参数改写为html
app.engine('html', require('express-art-template'))

使用:

// Express 为 Response 响应对象提供了一个方法 : render
// render 方法默认是不可以使用的,但是如果配置了模板引擎就可以使用了
// res.render('html模板名', {模板数据})
// render方法中第一个参数不能写路径,默认会去项目中的 views 目录查找该模板文件
// 也就是说 Express 有一个约定:开发人员把所有的视图文件都放到 views 目录中 
// Express 默认查找目录就是 views 目录
// 呈现视图并将呈现的HTML字符串发送到客户端
app.get('/', function (req, res) {
    res.render('404.art')
})

// 如果想要修改默认的views 为别的目录
// app.set('views', 'render函数的默认路径')
app.set('views', './views')


// 查找views 目录下的文件
app.get('/admin', function (req, res) {
    res.render('admin/index.html', {
        title : '管理系统'
    })
})

当需要直接返回页面的时候,也可以使用render方法

//当需要返回路径的时候
app.get('/', function (req, res) {
    res.render('index.html')
})

GET和POST请求获取数据

res.query是通过查询字符串来获取参数,只能获取get请求参数
1:get请求数据在请求行中,post需要设置请求行
2:GET没有请求体,post的请求数据在请求体中

在express 中获取表单 POST 请求体数据

在Express 中没有内置获取表单 POST 请求体的API,这里我们需要使用一个第三方中间件:body-parser

$ npm install body-parser

配置:

var express = require('express')
//0.先引包
var bodyParser = require('body-parser')

var app = express()

//配置 body-parser
//只要加入这个配置,则在 req 请求对象上会多出一个属性:body
//也就是说你可以直接通过 req.body 来获取表单 POST 请求体数据了
// parse application/x-www-form-urlencoded
app.use(bodyParser.urlencoded({ extended: false }))

// parse application/json
app.use(bodyParser.json())

//使用
app.use(function (req, res) {
  res.setHeader('Content-Type', 'text/plain')
  res.write('you posted:\n')
  //可以通过 req.body 来获取表单 POST 请求数据
  res.end(JSON.stringify(req.body, null, 2))
})

express 中设置状态码

express的响应对象response中有一个方法status()可以通过传递参数来设置响应码,该方法还可以链式编程,

res.status(500).send('hello')

在Node中如何操作 MongoDB 数据库

1: 使用官方的mongodb包来操作
可以查看官方文档 github 搜索 mongodb node
2 :使用第三方 mongoose 来操作 MongoDB 数据库
第三方包:mongoose基于MongoDB 官方的 mongodb包再做的一次封装.

安装: npm i mongoose

开启mongodb 数据库,然后执行例程代码

var mongoose = require('mongoose');

//连接MongoDB数据库,引号中的第一个为本机,第二个为本机的test数据库。
//指定连接的数据库不需要存在,当你插入第一条数据之后就会自动被创建出来
mongoose.connect('mongodb://localhost/test', { useMongoClient: true });

mongoose.Promise = global.Promise;

// 创建一个模型
// 就是在设计数据库
// MongoDB 是动态的,非常灵活,只需要在代码中设计你的数据库就可以了
// mongoose 这个包就可以让你的设计编写过程变得非常的简单
var Cat = mongoose.model('Cat', { name: String });
// Cat 为表名(最终生成名称为 cats),第二个参数为数据结构

// 实例化一个Cat 
var kitty = new Cat({ name: '喵喵'});

// 持久化保存 kitty 实例
kitty.save(function (err) {
  if (err) {
    console.log(err);
  } else {
    console.log('meow');
  }
});
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值