初入
nodejs.org
不是什么
不是一门语言、不是库、不是框架
是什么
。是一个基于ChromeV8引擎的javaScript运行时环境
。可以执行和解析JavaScript代码
。以前只有浏览器可以解析执行js
浏览器中的js
。ECMAScript(基本语法(var if function Object Array))
。BOM
。DOM
Node.js 中的js
。没有BOM\DOM
。ECMAScript
。在node.js这个JavaScript执行环境中为JavaScript提供了一下服务器级别的操作api
.文件读写
.网络服务构建
.网络通信
.http服务器
.等处理…
服务端是不操纵页面的
Node.js 特性
。事件驱动
。非阻塞IO模型(异步)
。轻量高效
npm是基于node.js开发出来的包管理工具
npm是世界上最大的开源库生态系统
绝大多数js相关的包都存放在了npm上,是为了让开发人员更方便的去下载使用
node.js能干什么
。web服务器后台
。命令行工具
.npm(node)
.webpack
.git(c++)
.hexo(node)
…
https://cnodejs.org
https://cnodejs.org/getStart
//-----------------------会触及---------------------------------
B/S编程模型
.Browser-Server
.back-end
.任何服务端技术这种BS编程模型都是一样,和语言无关
.Node只是作为我们学习BS编程模型的一个工具
模块化编程
.RequireJs
.SeaJs
.以前认知的JavaScript只能通过script标签加载
.在node中可以乡@inport()一样来引用加载JavaScript脚本文件
Node常用Api
异步编程
.回调函数
.Promise
.async
.generator
Express Web开发框架
Es6
//------------------------起步----------------------------//
下载 https://nodejs.org/en/download/
安装
一直下一步
已经安装过的,重新安装就会升级
cmd 查看node是否安装成功
node --version 或 node -v
环境变量
.
hello World /hello/hello.js
.解析执行javaScript
.读写文件 读写文件.js
.http http.js
Node中的JavaScript 模块系统
.EcmaScript(没有dom bom)
.核心模块
.是 node 提供的一个个具名的模块,都有自己特殊的名称标识
.node 为 JavaScript 提供了很多服务器级别的API,这些API绝大多数都被包装到了一个具名的核心模块中了。
例如:
fs 文件模块,
http服务构建的 http 模块,
path 路径操作模块,
url 请求路径操作模块,
os 操作系统信息模块
。。。。
使用核心模块 var xx = require(“xx”);//xx 模块名
.第三方模块 必须安装
.art-template
.用户自定义模块 模块导入.js
.require 默认空对象 {}
.var 自定义变量名称 = require('模块')
.作用
加载文件模块并执行里面的代码
拿到被加载文件模块导出的接口对象
.exports 默认空对象 {}
.node中是模块作用域,默认文件所有成员只在单前模块有效
.对于希望可以被其它模块访问的成员,我们需要把这些公开的成员都挂载到exports接口对象中 上
不能直接导出 方法/字符串/数字/数组 等,只能挂载
.导出多个成员(必须在对象中)
//exports.foo = "foo";
//exports.fun = function(){};
.导出单个成员(方法/字符串/数字/数组) module.exports 多个(包括exports.xxx) 后面覆盖前面
//module.exports = "foo"
//module.exports = {} //也可以导出多个成员
.exports 和 module.exports 区别
.原理
.exports 是 module.exports 的一个引用
在 node 中,每个模块内部都有一个自己的 module 对象
该 module 对象有一个成员 exports 也是一个对象
也就是说如果需要对外导出成员,只需要把导出的成员挂载到
//module.exports.xxx = xxx
每次导出成员 module.exports.xxx = xxx 很麻烦
所以node为了简化操作 专门提供了一个变量 exports = module.exports
//exports === module.exports 验证
当一个模块需要导出单个成员的时候
直接给 exports 赋值是没有用的
改变了 exports 的指向 不再指向 module.exports,所以重新赋值没有用,不能导出了
默认在代码最后有一句 return module.exports
.留言本
.requre 加载规则和加载机制
核心模块 require("模块名")
第三方模块 require("模块名")
自定义模块 require("模块路径") ;//一定要写 ./ 不然会被认为是核心模块 然后找不到报错
.优先加载缓存数据
main.js
require("./a")
var b = require("./b")
a.js
console.log("a.js loading")
var b = require("./b")
b.js
console.log("b.js loading")
module.exports = "bljs"
运行main.js
打印
a.js loading
b.js loading
由于 a.js 已经加载了 b.js,所以 main.js 不会重复加载b.js,
是为了避免重复加载,提高模块加载效率
main.js 的 require("./b")只是为了获取 b.js 导出的结构
.判断模块标识 require("模块标识")
.路径形式模块
以 ./ 单前目录不可省
../ 上一级目录不可省
/xxx(几乎不用)
首位的 / 在这里表示的是当前文件模块所属磁盘根目录
.js 后缀名可省
require("./foo")
.核心模块
核心模块文件已经被编译到了二进制文件中了,我们只需要按名字加载就行了
require("fs")
.第三方模块
不可能有如何一个第三方和核心模块名字是一样的
凡是第三方模块都必须通过 npm 来下载 使用时 require("模块名")
找 node_modules/模块名/package.json 文件
在找 json 文件中的 main 属性 记录了当前模块的入口模块
可以测试
在 node_modules 下新建 csA 文件夹
csA 下新建 package.json {"main":"index.js"}
下新建 index.js
console.log("csA 加载了")
module.exports = "测试 csA"
在 node_modules 同级目录下创建 app.js
var csA = require("csA")
console.log(csA)
运行 app.js
node app.js
如果 package.json 不存在 或 main指定入口也没有
则 node 会自动找该目录下的 index.js,index.js 会作为默认备选项
如果 以上条件不成立
则会进入上一级目录的 node_modules 目录查找 模块 在没有 ,在往上上一级,...
直至磁盘根目录,还没找到 会报错
can not find module xxx
.循环加载
commonJS模块规范
.模块化
.文件作用域
.通信规则 加载 导出
.javaScript 本身是不支持模块化的,在node中的js有一个很重要的概念,模块系统
.模块作用域
.使用require方法加载模块
.使用exports接口对象用来导出模块的成员
ip和端口号
所有联网的程序都要进行网络通信
而计算机中只有一个物理网卡,而且同一个局域网中,网卡的地址必须是唯一的
网卡是通过唯一的ip地址来进行定位的
1.ip地址用来定位计算机
2.端口号用来定位具体的应用程序
3.所有需要联网通信的软件都必须具有端口号(占用一个端口号)
4.范围0-65536
5.一些默认端口 尽量不要使用 如80
6.可以同时开启多个服务,但一定要确保端口号不同
Content-type
http://tool.oschina.net/commons
// 返回 HTML 页面 和 txt 文件 http-fs.js
Node中的 模块系统
在 node 中没有全局作用域的概念
在 node 中,只能通过 require 方法来加载执行多个 JavaScript 脚本
require 加载只能执行其中的代码,文件与文件之间由于是模块作用域,所以不会有污染的问题
模块完全是封闭的 内部无法访问外部 外部无法访问内部
模块作用域固然带来了一些好处,可以加载执行多个文件,可以完全避免变量命名污染
但是在某些情况下,模块与模块是要通信交互的
在每个模块中,都提供了 exports 120行
http
require
端口号
ip地址用来定位计算机
端口号用来定位具体的应用程序
Content-type
服务器最好把每次响应的数据是什么内容类型都告诉客户端
不同资源对应 Content-type 是不一样的 http://tool.oschina.net/commons
对应文本类型的数据,最好都加上编码,目的是为了防止中文解析乱码
通过网络发送文件
发送的并不是文件,本质上来讲是发送文件的内容
当浏览器接收到服务器响应内容之后,就会根据 Content-type 进行对应的解析处理
js代码风格
JavaScript Standard Style https://standardjs.com/readme-zhcn.html
当你采用了无分号的代码风格的时候,只需注意以下三种情况
当一行代码是以 ( [ ` 开头的时候,则在前面补上分号用于避免一些语法解析错误 ./hello/分号问题.js
Airbnb JavaScript Style
请求对象 Request
响应对象 Response
在 node 中使用模块引擎
统一处理静态资源
服务端渲染
就是在服务端使用模版引擎
模版引擎最早就是诞生于服务器领域,后来才发展到了前端
服务端渲染和客户端渲染的区别
客户端渲染 khd.png 不利于Seo(搜索引擎优化 渲染的数据,客户端异步渲染很难被爬虫抓取到)
服务端渲染 fwd.png 可以被搜索引擎抓取到的
真正的网站是由两者结合来做的
例如京东的商品列表就采用的服务端渲染,目的是为了Seo搜索引擎优化
而商品评论列表为了用户体验,而且也不需要SEO优化,所以采用客户端渲染
在网页右键能查看源代码 有相关内容 说明是服务端渲染
留言本
文件路径 和 模块路径
//模块标识中的 / 和 文件操作路径中的 /
// data/a.txt 相对当前目录
// ./data/a.txt 相对当前目录
// /data/a.txt 相对磁盘根目录
// c:/xx/xx 绝对路径
var fs = require("fs")
// 文件操作中的路径可以省略 ./
fs.readFile("data/a.txt", function (err, data) {})
// / 代表磁盘根目录 会到 C:\data\a.txt 查找
fs.readFile("/data/a.txt", function (err, data) {})
// 模块标识中的 相对路径 ./ 不可省略
var foo = require("./foo")
// /foo 相对磁盘根目录
修改完代码自动重启服务器
可以使用一个第三方命名导航工具 nodemon 来解决频繁修改代码重启服务问题
nodemon 是一个基于 node.js 开发的第三方命令行工具 需要全局安装
npm i -g nodemon
使用
nodemon app.js
只有是nodemon app.js 启动的服务,则他会监听文件的变化,当文件变化的时候,就会帮你自动重启服务器。
npm (node package manager node包管理)
npm init 初始化package.json
npm init -y 跳过向导,快速生成package.json
--save 会把安装的包名 添加到 package.json(包说明文件) 的dependencies
--save-dev
常用命令 https://www.npmjs.com/
install 可简写 i
--save 可简写 -S
uninstall 可简写 un
--global 可简写 -g
--global 全局 而非当前目录
npm -v / --version 查看版本·
npm install --global npm 升级nopm
npm install 一次性把 dependencies 依赖项 全部安装
npm install 包名 安装包
npm install 包名 --save 安装包并保存依赖项(package.json的dependencies)
npm uninstall 包名 删除包 如果有依赖项 依然报存
npm uninstall 包名 --save 删除包 删除包对应的依赖项 npm un 包名 -S
npm help 查看npm使用帮助
npm 命令 --help 查看具体命令的使用帮助 npm install --help
cnpm
npm 储存包文件在国外,有时候npm会被墙 下载速度较慢
http://npm.taobao.org/ 淘宝的开发团队 把npm在国内做了一个备份
// 安装 cnpm
$ npm install -g cnpm --registry=https://registry.npm.taobao.org
或
$ npm install -g cnpm
使用cnpm就会通过淘宝的服务器来下载jquery
npm i jquery
cnpm i jquery
如果不想安装 cnpm 又想用淘宝的服务器来下载
npm i jquery --registry=https://registry.npm.taobao.org
但是每次手动这样写参数很麻烦,所以可以把这个选项加入配置文件中
npm config set registry https://registry.npm.taobao.org
// 验证是否配置成功 查看配置信息
npm config list
只要设置了上面的配置,则以后所有的 npm install 都会默认通过淘宝服务器来下载
package.json(包说明文件)
"description":"项目描述"
"main":"入口文件"
"dependencies":{} //依赖
"keywords":"关键字"
"license":
package-lock.json 锁定版本
Express
原生的http在某些方面表现不足以应对开发需求,所以要使用框架来加快开发效率,让代码更高度统一
http://expressjs.com/
npm install express --save
公开指定目录
当以 /public/ 开头的时候,去 ./public/ 目录中查找对应的资源 推荐第一种
就可以通过 public/xxx 的方式访问 public目录中的所有资源了
app.use("/public/",express.static("./public/"))
// http://127.0.0.1:3000/public/public.html
当省略第一个参数的时候,则可以通过 省略 /public 的方式来访问 简写操作
app.use(express.static("./public/"))
// http://127.0.0.1:3000/public.html
必须是 /a/public 目录中的资源
app.use("/a/", express.static("./public/"))
// http://127.0.0.1:3000/a/public.html
app.get("/text",function(req,res){
var com = req.query //只能拿get请求参数
// res.statusCode = 302
// res.setHeader("Location","/")
// res.send()
res.redirect("/") //重定向
})
在express 获取 post 请求体数据
在express 中没有内置获取 post 参数 的API 需要使用一个第三方包 body-parser
npm i -S body-parser
配置 bodyParser 中间件
只要加入这个配置,则会在请求对象上会多出一个属性 body req.body
app.use(bodyParser.urlencoded({extended:false}))
app.use(bodyParser.json())
然后就可以 通过req.body获取参数
app.post("/text",function(req,res){
req.body //参数
}
Express crud
-
起步
- 初始化
- 模块处理
-
路由设计
请求方法 请求路径 get参数 post参数 作用 备注 get /studens -- -- 渲染首页 get /studens/new -- -- 渲染添加学生页面 post /studens -- name,msg,data 处理添加学生请求 get /studens/edit id -- 渲染编辑页面 post /studens/edit -- id,name,msg,data 处理编辑学生请求 get /studens/del id -- 处理删除请求
-
路由模块化
https://blog.csdn.net/weixin_42448623/article/details/103520490
封装 数据操作文件模块 文件db.json studens.js
MongoDB
文档 https://www.runoob.com/mongodb/mongodb-tutorial.html
下载
64 https://www.mongodb.com/dr/fastdl.mongodb.org/win32/mongodb-win32-x86_64-2012plus-4.2.2-signed.msi/download
32 https://www.mongodb.org/dl/win32/i382 要翻墙
测试安装成功
mongod -version
关系型数据库 和 非关系型数据库
关系型数据库
关系 表就是关系或者说表于表之间存在的关系
所有的关系型数据库都需要通过 sql 语言来操作
所有的关系型数据库在设计前都需要设计表结构
支持约束(唯一,主键,默认值,非空)
非关系型数据库
非常的灵活
有的非关系型数据库就是 键值对
MongoDB 是长的最像 关系型数据库 的 非关系型数据库
数据库 --》数据库
数据表 --》集合(数组)
表记录 --》文档对象
MongoDB 不需要设计表结构
也就是说可以任意的往里面存放数据,没有结构性一说
开启/关闭 MongoDB 服务
启动MongoDB服务 net start MongoDB
关闭MongoDB服务 net stop MongoDB 或直接关闭cmd窗口 ctrl+c
连接数据库
C:\mongodb\bin\mongo.exe
基本命令 在mongo.exe运行
show dbs 查看数据库列表
db 查看当前操作的数据库
use 数据库名 切换到指定数据库(如果没有会新建)
show collections 查看集合
插入数据
db.studens.insertOne({"name":"添加数据"})
db.studens.find() 查询所有studens中的数据
node 操作 mongodb
使用官方的 mongodb 包来操作
https://github.com/mongodb/node-mongodb-native
使用第三方 mongoose 来操作 MongoDB 数据库
mongoose 是基于 MongoDB 官方的 mongodb 包再一次做了封装
官网 https://mongoosejs.com/
中文版 http://www.mongoosejs.net/
安装
npm i mongoose
node 操作 mySql
git地址 https://github.com/mysqljs/mysql
启动mysql
安装 npm i mysql
示例
var mysql = require("mysql")
// 创建连接
var connection = mysql.createConnection({
host : 'localhost',
user : 'root',
password : '123456',
database : 'my_db'
});
// 连接数据库
connection.connect();
// 执行数据操作
connection.query('SQl 语句', function (error, results, fields) {
if (error) throw error;
console.log('The solution is: ', results[0].solution);
});
// 关闭连接
connection.end();
如果需要获取一个函数中异步操作的结果,则必须通过回调函数来获取
https://blog.csdn.net/weixin_42448623/article/details/103564943
封装原生ajax
function get(url,fun){
var xhr
if(window.XMLHttpRequest){
xhr = new XMLHttpRequest()
}else{
xhr = new ActiveXObject()
}
xhr.open(“GET”,url)
xhr.onreadystatechange = function(){
if(xhr.status == 200 && xhr.readyState == 4){
console.log(xhr.responseText)
fun(null,xhr.responseText)
}
}
xhr.send()
}
get(url,function(err,data){
})
其他核心模块
做一个小管理系统
+GRUD
Express Web开发框架 npm install express