由于Node服务器端运行环境中,没有浏览器和HTML的概念,所以Node中剔除了DOM和BOM对象模型,取而代之的是全局成员和核心API模块
LTS和Current版本区别
- LTS:【推荐在企业中使用】,是长期稳定版的安装包,运行稳定、安全;
- Current:【推荐学习或尝鲜去使用】,是最新特征版,这个安装包中有最新的Node特性
C:\Users\阿怼\Desktop> node .\node.js
cls
清屏node
进入REPL环境 按 Ctrl+C 两次退出node -v
检查Node版本,也可检查Node是否安装成功cd
路径 到…文件夹路径cd..
返回上一级路径使用模块前需要先调用
const
设定为常量
const 名称 = require('核心模块名');
fs
模块提供了一个 API,用于以模仿标准 POSIX 函数的方式与文件系统进行交互。要使用此模块:
(要先调用)
const fs = require('fs');
fs.readFile(path[, options], callback)
path
| | | 文件名或文件描述符,文件路径–表示要读取的文件路径options
| –表示要一什么样的编码格式,来都读取指定的文件,默认编码格式为NULL
callback
--表示当文件读取完成用callback函数处理
const fs = require('fs')
fs.readFile('./1.txt', 'utf-8', function(err, data) {
if (err) {
console.log('读取错误:' + err.message);
}
console.log('读取成功' + data);
})
fs.writeFile(file, data[, options], callback)
异步地将数据写入到一个文件,如果文件已存在则覆盖该文件。 data 可以是字符串或 buffer。
const fs = require('fs')
fs.writeFile('./2.txt', '嘿嘿嘿', function(err) {
if (err) return console.log('写入错误:' + err.message)
console.log('写入成功');
})
fs.appendFile(path, data[, options], callback)
异步地将数据追加到文件,如果文件尚不存在则创建该文件。 data 可以是字符串或 Buffer。
const fs = require('fs')
fs.appendFile('./2.txt', '\n嘻嘻嘻', (err)=> {
if (err) return console.log('追加错误:' + err.message)
console.log('追加成功');
})
使用 fs 模块操作文件的时候,如果提供的操作路径是 相对路径, 则会根据当前执行node命令时的磁盘目录,去拼接提供的文件的相对路径,从而容易出现问题;例如:
const fs = require('fs')
// 调用 fs.readFile 方法时,提供的第一个参数是相对路径,容易出现问题
fs.readFile('./files/1.txt', 'utf-8', (err, data) => {
if(err) return console.log(err.message)
console.log(data)
})
__dirname
来解决 fs 模块操作文件时候的路径问题
__dirname
表示当前这个文件所在的磁盘目录
const fs = require('fs')
fs.readFile(__dirname + '/1.txt', 'utf-8', (err, data) => {
if (err) return console.log(err.message)
console.log('文件内容为:' + data)
console.log('磁盘目录为:' + __dirname)
console.log('文件路径为:' + __dirname + '/1.txt')
})
// 文件内容为:哈哈哈哈哈
// 磁盘目录为:C:\黑马程序员\就业班\笔记\node.js
// 文件路径为:C:\黑马程序员\就业班\笔记\node.js/1.txt
补充:
__dirname
表示当前这个文件执行的时候所处的根目录,只代表一层目录而已(可变)
__filename
表示当前这个文件执行的时候的完整路径,包含了具体文件名
fs.Stats
对象提供有关文件的信息。
fs.stat(path[, options], callback)
stat(2)
。 回调有两个参数 (err, stats)
,其中 stats
是 fs.Stats
。err.code
将是常见系统错误之一。fs.open()
、 fs.readFile()
或 fs.writeFile()
之前使用 fs.stat()
检查文件是否存在。 而是应该直接打开、读取或写入文件,如果文件不可用则处理引发的错误。fs.access()
。
const fs = require('fs')
fs.stat(__dirname + '/1.txt', (err, stats) => {
if (err) return console.log(err.message)
// 大小
console.log(stats.size);
// 创建时间
console.log(stats.birthtime);
// 是否为文件
console.log(stats.isFile());
// 是否为目录
console.log(stats.isDirectory());
})
// 15
// 2019-07-19T01:14:02.809Z
// true
// false
Stats
返回信息
const fs = require('fs')
fs.stat(__dirname + '/1.txt', (err, stats) => {
if (err) return console.log(err.message)
console.log(stats);
})
// 返回文件信息(对象)
Stats {
dev: 1381884629,
mode: 33206,
nlink: 1,
uid: 0,
gid: 0,
rdev: 0,
blksize: 4096,
ino: 15481123719203076,
size: 15,
blocks: 0,
atimeMs: 1563498842809.0007,
mtimeMs: 1563503649468.5012,
ctimeMs: 1563503649468.5012,
birthtimeMs: 1563498842809.0007,
atime: 2019-07-19T01:14:02.809Z,
mtime: 2019-07-19T02:34:09.469Z,
ctime: 2019-07-19T02:34:09.469Z,
birthtime: 2019-07-19T01:14:02.809Z
}
fs.copyFile(src, dest[, flags], callback)
异步地将
src
拷贝到dest
。 默认情况下,如果dest
已经存在,则覆盖它。 除了可能的异常,回调函数没有其他参数。 Node.js 不保证拷贝操作的原子性。 如果在打开目标文件用于写入后发生错误,则 Node.js 将尝试删除目标文件。
fs.constants.COPYFILE_EXCL
| fs.constants.COPYFILE_FICLONE
)。
fs.constants.COPYFILE_EXCL
- 如果 dest
已存在,则拷贝操作将失败。fs.constants.COPYFILE_FICLONE
- 拷贝操作将尝试创建写时拷贝(copy-on-write)链接。如果平台不支持写时拷贝,则使用后备的拷贝机制。fs.constants.COPYFILE_FICLONE_FORCE
- 拷贝操作将尝试创建写时拷贝链接。如果平台不支持写时拷贝,则拷贝操作将失败。
const fs = require('fs')
fs.copyFile(__dirname + '/1.txt', __dirname + '/1-copy.txt', (err) => {
if (err) return console.log(err.message)
console.log('copy成功');
})
path
模块提供用于处理文件路径和目录路径的实用工具。 它可以使用以下方式访问:
const path = require('path');
...paths
路径片段的序列。- 返回:
path.join()
方法使用平台特定的分隔符作为定界符将所有给定的path
片段连接在一起,然后规范化生成的路径。- 零长度的
path
片段会被忽略。 如果连接的路径字符串是零长度的字符串,则返回'.'
,表示当前工作目录。
path.join('/foo', 'bar', 'baz/asdf', 'quux', '..');
// 返回: '/foo/bar/baz/asdf'
path.join('foo', {}, 'bar');
// 抛出 'TypeError: Path must be a string. Received {}'
// 应用
fs.readFile(path.jion(__dirname , './1.txt'), 'utf-8', (err, data) => {
if (err) return console.log(err.message)
console.log('文件内容为:' + data)
})
'foo/bar/baz'.split(path.sep);
// 返回: ['foo', 'bar', 'baz']
'foo\\bar\\baz'.split(path.sep);
// 返回: ['foo', 'bar', 'baz']
- path
- ext 可选的文件扩展名。
- 返回:
path.basename()
方法返回path
的最后一部分,类似于 Unix 的basename
命令。
path.basename('/foo/bar/baz/asdf/quux.html');
// 返回: 'quux.html'
path.basename('/foo/bar/baz/asdf/quux.html', '.html');
// 返回: 'quux'
- path
- 返回:
- path.dirname() 方法返回 path 的目录名,类似于 Unix 的 dirname 命令。
path.dirname('/foo/bar/baz/asdf/quux');
// 返回: '/foo/bar/baz/asdf'
- path
- 返回:
path.extname()
方法返回path
的扩展名,从最后一次出现 .(句点)字符到 path 最后一部分的字符串结束。 如果在path
的最后一部分中没有.
,或者如果path
的基本名称(参阅path.basename()
)除了第一个字符以外没有 .,则返回空字符串。
path.extname('index.html');
// 返回: '.html'
path.extname('index.coffee.md');
// 返回: '.md'
path.extname('index.');
// 返回: '.'
path.extname('index');
// 返回: ''
path.extname('.index');
// 返回: ''
path.extname('.index.md');
// 返回: '.md'
集合展示
const path = require('path')
// console.log(path.sep) // 路径分隔符
const str = 'c:/a/b/c/1.txt'
console.log(path.basename(str))
// 获取文件名称的
console.log(path.dirname(str))
// 获取文件所在的路径的
console.log(path.extname(str))
// 获取文件的扩展名
创建WEB基本服务器
// 导入http核心模块
const http = require('http')
// 调用http.createServer()方法,创建一个服务器对象
const server = http.createServer()
// 为server服务器绑定监听函数,通过 on 方法,绑定request事件,来监听客户的请求
// req 表示客户端相关的参数
// res 表示和服务器相关的参数和方法
server.on("request", function(req, res) {
// 设置响应头 解决中文乱码 状态码:200
res.writeHeader(200, {
'Content-Type': 'text/plain;charset=utf-8'
})
res.end('哈哈哈')
})
// 启动服务器
server.listen(3000, '127.0.0.1', function() {
console.log('server running at http://127.0.0.1:3000')
})
querystring
模块提供用于解析和格式化 URL 查询字符串的实用工具
const querystring = require('querystring');
querystring.parse(str[, sep[, eq[, options]]])
str
要解析的 URL 查询字符串。sep
用于在查询字符串中分隔键值对的子字符串。默认值: '&'
。eq
用于在查询字符串中分隔键和值的子字符串。默认值: '='
。options
decodeURIComponent
解码查询字符串中的百分比编码字符时使用的函数。默认值: querystring.unescape()
。maxKeys
指定要解析的键的最大数量。指定 0
可移除键的计数限制。默认值: 1000
。
querystring.parse()
方法将 URL 查询字符串 str 解析为键值对的集合。
例如,查询字符串 'foo=bar&abc=xyz&abc=123'
被解析为:
{
foo: 'bar',
abc: ['xyz', '123']
}
模块成员,根据一些区别可以分为三类
- 核心模块
require('核心模块标识符')
Node.js 安装时 全部附带安装- 第三方模块
require('第三方模块标识符')
在npm上下载的模块- 用户自定义模块
require('路径标识符')
程序猿自己写的js文件
Packages
,包是在模块基础上更深一步的抽象;CommonJS
规范实现的 应用程序 或 类库;package.json
必须在包的顶层目录下;package.json
文件必须符合 JSON 格式,并且必须包含如下三个属性:name, version, main
name:包的名称,必须是唯一
description:包的简要说明
version:符合语义化版本识别规范的版本字符串
keywords:关键字数据,通常用于搜索
maintainers:维护者数组,每个元素要包含name、email、web可选字段
contributors:贡献者数组,格式与maintainers相同。包的坐着应该是贡献者数据的第一个元素
bugs:提交bug的地址,可以是网址或者电子邮件地址
licenses:许可证数组,每个元素要包含type和url字段
repositories:仓库托管地址数组,每个元素要包含type、url和path字段
dependencies:包的依赖,一个关联数组,由包名称和版本号组成。
devDependencies:开发依赖项,表示一个包在开发期间用到的依赖项
在 Node.js 中被广泛使用,它泛指一种特定的设计模式、一系列的处理单元、过滤器和处理程序,以函数的形式存在,连接在一起,形成一个异步队列,来完成对任何数据的预处理和后处理。
它的优点在于 灵活性:使用中间件我们用极少的操作就能得到一个插件,用最简单的方法就能将新的过滤器和处理程序扩展到现有的系统上。
[外链图片转存失败(img-48C8RC6r-1566292781253)(en-resource://database/1441:1)]
创建
Express
应用程序。该express()
函数是express模块
导出的顶级函数。
const express = require('express');
const app = express();
// 导入express
const express = require('express');
// 调用express()创建服务器
const app = express();
// 调用app.get()方法,监听客户端的请求,并指定要监听的URL地址和处理函数
app.get('/', (req, res)=>{
res.send('hello world');
});
// 调用app.listen() 方法启动服务器
app.listen(3000,()=>{
console.log('serve running at http://127.0.0.1:3000');
});
app.get('/', function (req, res) {
res.send('GET request to homepage');});
app.post('/', function (req, res) {
res.send('POST request to homepage');});
1.res.send([body])
res.send(new Buffer('whoop'));
res.send({ some: 'json' });
res.send('some html
');
res.status(404).send('Sorry, we cannot find that!');
res.status(500).send({ error: 'something blew up' });
res.sendFile(path [,options] [,fn])
path
。Content-Type
根据文件名的扩展名设置响应HTTP标头字段。除非root
在options
对象中设置了该选项,path
否则必须是该文件的绝对路径。
app.get('/file/:name', function (req, res, next) {
var options = {
root: __dirname + '/public/',
dotfiles: 'deny',
headers: {
'x-timestamp': Date.now(),
'x-sent': true
}
};
var fileName = req.params.name;
res.sendFile(fileName, options, function (err) {
if (err) {
next(err);
} else {
console.log('Sent:', fileName);
}
});
});
const express = require('express')
const path = require('path')
const app = express()
app.get('/', (req, res) => {
// 1. 注意:sendFile 如果只给定一个参数的时候,这个参数必须是绝对路径,表示要发送给客户端的文件的路径
// res.sendFile('./views/home.html')
// res.sendFile(path.join(__dirname, './views/home.html'))
// 2. 为 res.sendFile 方法,提供两个参数进行调用
// 第一个实参就可以传递一个相对路径了;第二个实参,必须是一个绝对路径;
res.sendFile('./views/home.html', { root: __dirname })
})
app.get('/movie', (req, res) => {
res.sendFile('./views/movie.html', { root: __dirname })
})
app.get('/about', (req, res) => {
res.sendFile('./views/about.html', { root: __dirname })
})
app.listen(3000, () => {
console.log('server running at http://127.0.0.1:3000')
})
express.static(root,[options])
这是Express
中的内置中间件功能。它提供静态文件,基于 serve-static
。
该
root
参数指定从中提供静态资产的根目录。该函数通过req.url
与提供的root目录组合来确定要提供的文件。当找不到文件时,它不是发送404响应,而是调用next()
继续下一个中间件,允许堆叠和回退。
app.use(express.static('public'))
;
app.use()
方法,是专门用来注册 中间件;express.static
是express的内置中间件;app.use('/虚拟目录', express.static('public'))
const express = require('express')
const app = express()
// app.use() 的作用,就是注册中间件
// express.static() 方法,可以把 指定的 目录,托管为静态资源目录,这样,指定目录下的所有文件,
// 都可以直接被 浏览器来访问
// app.use(express.static('./views'))
// 可以在托管静态资源文件的时候,指定要挂载的虚拟路径;
app.use('/page', express.static('./views'))
app.listen(3000, () => {
console.log('server running at http://127.0.0.1:3000')
})
npm i ejs -S
app.set()
配置默认的模板引擎 app.set('view engine', 'ejs')
app.set()
配置默认模板页面的存放路径 app.set('views', './views')
res.render()
来渲染模板页面res.render('index.ejs', { 要渲染的数据对象 })
注意:模板页面的后缀名,可以省略不写!
const express = require('express')
const app = express()
// 1. 使用 app.set('view engine', '模板引擎的名称') 固定格式
app.set('view engine', 'ejs')
// 2. 设置模板页面的默认存放路径 app.set('views', '模板页面的具体存放路径')
app.set('views', './ejs_pages')
app.get('/', (req, res) => {
// 注意:如果想要调用 res.render 函数来渲染页面,必须先配置模板引擎
res.render('index.ejs', { name: 'cxk', age: 20, hobby: ['唱', '跳', 'rap','打篮球'] })
})
app.listen(3000, () => {
console.log('server running at http://127.0.0.1:3000')
})
cnpm i art-template express-art-template -S
app.engine('自定义模板引擎的名称', 渲染函数)
app.set('view engine', '具体模板引擎的名称')
app.set('views', '路径')
注意:配置模板引擎和文件后缀名要和自定义的模板引擎名称一致
const express = require('express')
const app = express()
// 1. 使用 app.engine() 方法自定义模板引擎
app.engine('html', require('express-art-template'))
// 2. 使用 app.set('view engine', '指定模板引擎名称') 来配置项目中用到的模板引擎
app.set('view engine', 'html')
// 3. 配置模板页面的存放路径
app.set('views', './art_page')
app.get('/', (req, res) => {
res.render('index.html', { name: 'cxk', age: 20, hobby: ['唱', '跳', 'rap','打篮球'] })
})
app.listen(3000, () => {
console.log('server running at http://127.0.0.1:3000')
})
创建一个新的路由器对象。
var router = express.Router([options]);
// 1. 封装单独的 router.js 路由模块文件
const express = require('express')
// 创建路由对象
const router = express.Router()
router.get('/', (req, res)=>{})
router.get('/movie', (req, res)=>{})
router.get('/about', (req, res)=>{})
// 导出路由对象(暴露)
module.exports = router
定义:中间件就是一个处理函数,只不过这个函数比较特殊,包含了三个参数,分别是req,res,next
注意:中间件方法中的三个参数:
- req:请求对象;
- res:响应对象;
- next:next()可以被调用,表示调用下一个中间件方法;
app.get('URL地址', (req, res, next)=> {})
;router.get('url地址', (req, res, next)=>{})
app.use((err, req, res, next)=>{})
express.static()
配置数据库环境
// 1. 导入 mysql 模块
const mysql = require('mysql')
// 2. 创建mysql的连接对象
const conn = mysql.createConnection({
host: 'localhost',
user: 'root',
password: 'root',
database: 'mysql_001'
})
查询
const sqlStr1 = 'select * from users'
conn.query(sqlStr1, (err, result) => {
if (err) return console.log('获取数据失败!' + err.message)
console.log(result)
})
新增
const user = { uname: '小黄', age: 12, gender: '男' }
const sqlStr2 = 'insert into users set ?'
conn.query(sqlStr2, user, (err, result) => {
if (err) return console.log('插入数据失败!' + err.message)
console.log(result)
})
更改
const user = { id: 2, uname: '小绿', age: 22 }
const sqlStr3 = 'update users set ? where id=?'
// 注意:在 执行 conn.query 的时候,如果sql语句中,包含了 多个 ? 占位符,则,
// 第二个实参,必须传递一个数组,数组中的每一项,都要和 sql 语句中的 ? 对应上
conn.query(sqlStr3, [user, user.id], (err, result) => {
if (err) return console.log('修改数据失败!' + err.message)
console.log(result)
})
删除
const sqlStr4 = 'delete from users where id=?'
conn.query(sqlStr4, 2, (err, result) => {
if (err) return console.log('删除失败!' + err.message)
console.log(result)
})
提醒:熟练掌握SQL语句很重要,勤加练习