第一天
一. 使用http模块API
1. 回调响应
// 不推荐使用 res.write('hello') res.write(' world') res.end() // 推荐使用 res.end('hello world')
4. 设置Content-Type
(text/plain)数据类型可以看网址:https://tool.oschina.net/commons
如果返回的是图片数据就不要指定编码了,我们常说的编码是字符编码
// 通知浏览器返回普通字符串文本数据;utf-8编码。让浏览器用相应编码去解码数据,不至于乱码 res.setHeader('Content-Type', 'text/plain; charset=utf-8')
5. 读取文件出错返回return
阻止node.js的后续代码执行,方法返回值
6. 根据客户端请求返回不同资源
解析客户端请求路径
判断利用fs文件读写模块返回不同资源
7. 使客户端重定向
设置状态码为302:临时重定向浏览器不会记住
在响应头告诉客户端重定向网址
客户端收到302就会去location找跳转地址跳过去
res.statusCode = '302' res.setHeader('Location', '/') res.end()
注:如果使用301永久重定向,那么只要访问一次浏览器就会缓存记住,下次就不会请求服务端会直接跳转过去
二. node.js使用模板引擎:例:art-template
模板引擎不关心你的字符串内容,只关心自己能认识的模板标记语法,如:{{}}
1. art-template不仅能在浏览器使用也能在node.js使用
// 安装: npm install art-template // 引入,npm是什么requeire就是什么: var template = require('art-template')
// 根据api进行调用
2. 服务端渲染和客户端渲染
渲染就是看模板引擎在哪里使用:
服务端渲染:服务端使用模板引擎返回给客户端渲染后的html
客户端渲染:客户端使用模板引擎,通过ajax从服务端拿到数据渲染页面
两者渲染区别:
客户端渲染不利于SEO搜索引擎优化(找不到你,解析不了你的内容)
服务端渲染可以被爬虫抓取到,客户端渲染时很难被爬虫抓到的
三. 使用url模块API
1. 获得链接get参数
url.parse(urlString,boolean,boolean)
parse这个方法可以将一个url的字符串解析并返回一个url的对象
参数:urlString指传入一个url地址的字符串
第二个参数(可省)传入一个布尔值,默认为false,为true时,返回的url对象中,query的属性为一个对象。
var url = request('url') var obj = url.parse('/test?name=ming&messape=hello') // 拿到?后面参数并转成json字符串 console.log(obj.query)
四. 进入REPL(交互式解释器)
类似 Window 系统的终端或 Unix/Linux shell,就像浏览器的调试窗口console,我们可以在终端中输入命令,并接收系统的响应。轻量级即编即用
Node 自带了交互式解释器,可以执行以下任务:
-
读取 - 读取用户输入,解析输入了Javascript 数据结构并存储在内存中。
-
执行 - 执行输入的数据结构
-
打印 - 输出结果
-
循环 - 循环操作以上步骤直到用户两次按下 ctrl-c 按钮退出。
我们可以输入以下命令回车来启动 Node 的终端:
node
第二天
一. 服务端语言 + 运行环境(提供API,编译器,持续运行)
Apache和Nginx封装了很多底层变成配置文件,还封装了很多底层提供API,让语言编写更加简单
Node更灵活,没有封装底层,需要自己用语言编写
PHP + Apache
PHP + Nginx
JS + Node
二. commenJS语法,模块管理
1.. 引入模块
引入内部模块需要用相对路径,如:
var t = require('./test')
引入模块优先从缓存中加载,所以如果这个模块被引用过了,其他模块再引用这个模块,它不会执行代码,只会拿到这个模块对象:简单来说模块代码不管被引用多少次,它只会执行一次
2. 模块作用域
node没有全局作用域,只有模块作用域,每个模块即使相同命名也毫不影响
node模块之间通讯利用exports:可以导出多个成员利用对象
// 模块a exports.test = 'hello' // 模块b // request('./a')等价模块a的exports var ret = request('./a') console.log(ret.test)
直接导出单个成员,也可以导出多个成员给module.exports赋值对象就行
// 模块a // 错误导出:exports = 'hello' // 正确导出:也可以导出方法 module.exports = 'hello' // 模块b var ret = request('./a') console.log(ret)
3. 导出原理:
node为了简化操作默认会有一个exports,如果直接赋exports值会生成新的引用,这时exports和module.exports指向不同引用,那么导出的module.exports没有赋值自然就是空对象了
// 默认每个模块隐含代码
var module {
exports: {}
}
// node为了简化操作默认代码,指针指向同一对象
var exports = module.exports
// 我们的代码就是写在这
return module.exports;
第三天
一. 修改完代码自动重启服务
使用第三方工具启动服务:nodemon,当代码发生变化会自动重启服务
1. 安装:npm install --global nodemon
2. 启动服务: nodemon app.js
二. 传统http和express区别
三. 懒人显示启动服务
// 获得本机ip方法定义
var os = require('os');
function getIPAdress() {
var interfaces = os.networkInterfaces();
for (var devName in interfaces) {
var iface = interfaces[devName];
for (var i = 0; i < iface.length; i++) {
var alias = iface[i];
if (alias.family === 'IPv4' && alias.address !== '127.0.0.1' && !alias.internal) {
return alias.address;
}
}
}
}
// 启动服务提示
server.listen(3000, () => {
console.log('本机地址:x1B[36m%sx1B[0m', 'http://localhost:3000');
console.log('局域网地址:x1B[36m%sx1B[0m', 'http://' + getIPAdress() + ':3000');
});
第四天
如果想要获得一个函数中异步操作内容,必须通过回调函数来获取,传入回调函数给这个函数
第五天
使用MongoDB
一. 安装数据库,配置环境变量
二. 开关MongoDB数据库
注:默认使用执行DOS命令mongod所处盘符下根目录下的/data/db
所以在第一次执行命令启动服务时要自己手动新建一个/data/db,不然找不到此目录会启动服务失败
// 启动服务 mongod
// 关闭服务
1. 在开启服务的控制台,直接Ctrl+C即可停止
2. 或者直接关闭开启服务的控制台也可以
三. 连接数据库
// 默认连接本地开启的MongoDB数据库 mongo
// 退出连接 exit
第六天
使用MongoDB的云数据库
教程链接:https://www.cnblogs.com/xybaby/p/9460634.html
第七天
一. path路径操作模块
参考文档:https://nodejs.org/docs/latest-v13.x/api/path.html
- path.basename:获取路径的文件名,默认包含扩展名
- path.dirname:获取路径中的目录部分
- path.extname:获取一个路径中的扩展名部分
- path.parse:把路径转换为对象
- root:根路径
- dir:目录
- base:包含后缀名的文件名
- ext:后缀名
- name:不包含后缀名的文件名
- path.join:拼接路径
- path.isAbsolute:判断一个路径是否为绝对路径
二. Node中的其它成员(__dirname,__filename)
在每个模块中,除了require
,exports
等模块相关的API之外,还有两个特殊的成员:
-
__dirname
,是一个成员,可以用来动态获取当前文件模块所属目录的绝对路径 -
__filename
,可以用来动态获取当前文件的绝对路径(包含文件名) -
__dirname
和filename
是不受执行node命令所属路径影响的
在文件操作中,使用相对路径是不可靠的,因为node中文件操作的路径被设计为相对于执行node命令所处的路径。
所以为了解决这个问题,只需要把相对路径变为绝对路径(绝对路径不受任何影响)就可以了。
就可以使用__dirname
或者__filename
来帮助我们解决这个问题
在拼接路径的过程中,为了避免手动拼接带来的一些低级错误,推荐使用path.join()
来辅助拼接
var fs = require('fs');
var path = require('path');
// console.log(__dirname + 'a.txt');
// path.join方法会将文件操作中的相对路径都统一的转为动态的绝对路径
fs.readFile(path.join(__dirname + '/a.txt'),'utf8',function(err,data){
if(err){
throw err
}
console.log(data);
});
三. 子模板和模板的继承(模板引擎高级语法)【include,extend,block】
<!DOCTYPE html>
<html lang="zh">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>模板页</title>
<link rel="stylesheet" href="/node_modules/bootstrap/dist/css/bootstrap.css"/>
{{ block 'head' }}{{ /block }}
</head>
<body>
<!-- 通过include导入公共部分 -->
{{include './header.html'}}
<!-- 留一个位置 让别的内容去填充 -->
{{ block 'content' }}
<h1>默认内容</h1>
{{ /block }}
<!-- 通过include导入公共部分 -->
{{include './footer.html'}}
<!-- 公共样式 -->
<script src="/node_modules/jquery/dist/jquery.js" ></script>
<script src="/node_modules/bootstrap/dist/js/bootstrap.js" ></script>
{{ block 'script' }}{{ /block }}
</body>
</html>
<!-- 继承(extend:延伸,扩展)模板也layout.html -->
<!-- 把layout.html页面的内容都拿进来作为index.html页面的内容 -->
{{extend './layout.html'}}
<!-- 向模板页面填充新的数据 -->
<!-- 填充后就会替换掉layout页面content中的数据 -->
<!-- style样式方面的内容 -->
{{ block 'head' }}
<style type="text/css">
body{
background-color: skyblue;
}
</style>
{{ /block }}
{{ block 'content' }}
<div id="">
<h1>Index页面的内容</h1>
</div>
{{ /block }}
<!-- js部分的内容 -->
{{ block 'script' }}
<script type="text/javascript">
</script>
{{ /block }}
四. 中间件
注意:MongoDB数据设计时间戳
// 时间戳数据字设计
create_time: {
type: Date,
// 注意:这里不要写Date.now(),因为会即刻调用
// 这里直接给了一个方法,如果创建数据的时候没有传create_time,这时mongoose就会自动调用这个方法赋值
default: Date.now
}
使用express-session