01Node.js
Node.js是什么
- 帮助大家打开服务端,只有懂得服务端才能更好配合服务器开发人员进行协同开发
- Java/PHP/Python/Ruby/.Net/Node.js
官方解释
-
Node.js不是一门语言,也不是库或者框架,是JavaScript运行时的环境,简单来讲就是Node.js可以解析和运行JavaScript代码,现在JavaScript可以完全脱离浏览器
-
Node.js中的JavaScript
- 没有BOMDOM
- EcmaScript
- 在Node这个JavaScript执行环境中为JavaScript提供了一些服务器就级别的操作API
- 文件读写
- 网络服务的构建
- 网络通信
- http服务器
- .......
- 构建
- event-driven 事件驱动
- non-blocking I/O model 非阻塞IO模型(异步)
- lightweight and efficent 轻量和高效
- npm是世界上最大的开源库生态系统
- 绝大多数JavaScript相关的包都存放在npm上,方便下载eg
npm install jquery
Node.js可以做什么?
- web服务器后端
- 命令行工具
- npm(node)
- git(C)
- hexo(node)
- ..
- 使用第三方
- webpack
- gulp
- npm
require方法
概念
require 是一个方法,它的作用就是用来加载模块的
在 Node 中,模块有三种:
-
具名的核心模块,例如 fs、http
-
用户自己编写的文件模块
相对路径必须加 ./
可以省略后缀名
相对路径中的 ./ 不能省略,否则报错 -
在 Node 中,没有全局作用域,只有模块作用域
- 外部访问不到内部
- 内部也访问不到外部
- 默认都是封闭的
既然是模块作用域,那如何让模块与模块之间进行通信,我们加载文件模块的目的不是为了简简单单的执行里面的代码,更重要是为了使用里面的某个成员
作用
require 方法有两个作用:
- 加载文件模块并执行里面的代码
- 拿到被加载文件模块导出的接口对象
exports
- 在每个文件模块中都提供了一个对象:exports
exports 默认是一个空对象,要把所有需要被外部访问的成员挂载到这个 exports 对象中
使用方法
request 请求事件处理函数,需要接收两个参数:
- request 请求对象
- 请求对象可以用来获取客户端的一些请求信息,例如请求路径
- response 响应对象
- 响应对象可以用来给客户端发送响应消息
- response 对象有一个方法:write 可以用来给客户端发送响应数据
- write 可以使用多次,但最后要使用 end 来结束响应,否则客户端会一直等待,告诉客户端结束了,呈递给用户了
response.end()
- 可以直接 end 的同时发送响应数据
res.end('hello nodejs')
- res.end()里面只接受字符串,需要用JSON.stringfy(xxx)进行转字符串
- write 可以使用多次,但最后要使用 end 来结束响应,否则客户端会一直等待,告诉客户端结束了,呈递给用户了
根据不同的请求路径发送不同的响应结果
- 获取请求路径
req.url 获取到的是端口号之后的那一部分路径,也就是说所有的 url 都是以 / 开头的 - 判断路径处理响应
require 加载 fs 核心模块
fs 核心模块
fs 是 file-system 的简写,就是文件系统的意思,在 Node 中如果想要进行文件操作,就必须引入 fs 这个核心模块
在 fs 这个核心模块中,就提供了所有的文件操作相关的 API
fs.readFile()
就是读取文件的
-
第一个参数就是读取文件路径
-
第二个参数就是一个回调函数
-
成功
- data:数据
- error: null
-
失败
- data: undefined
- error :错误对象
fs.readFile('./data/a.txt', function (error, data) {
if (error) {
console.log('读取文件失败了')
} else {
console.log(data.toString())
}
})
fs.writeFile()
写文件的
- 第一个参数:文件路径
- 第二个参数:文件内容
- 第三个参数:回调函数
- 成功:error:null
- 失败:error错误对象
fs.writeFile('./data/你好.md', '大家好,给大家介绍一下,我是Node.js', function (error) {
if (error) {
console.log('写入失败')
} else {
console.log('写入成功')
}
})
http 创建编写服务器
服务器作用
- 提供服务:对数据的服务
- 发请求
- 接收请求
- 处理请求
- 给个反馈(发送响应)一个请求对应一个响应,如果在一个请求的过程中,已经结束响应了,则不能重复发送响应。
- 注册 request 请求事件
- 当客户端请求过来,就会自动触发服务器的 request 请求事件,然后执行回调处理函数
使用方法
一、加载 http 核心模块
var http = require('http')
二、使用 http.createServer() 方法创建一个 Web 服务器,返回一个 Server 实例
var server = http.createServer(function(req,res){})
三、打开服务器并作出响应
server.on('request', function () {
console.log('收到客户端的请求了')
})
四、绑定端口号,启动服务器
server.listen(3000, function () {
console.log('服务器启动成功了,可以通过 http://127.0.0.1:3000/ 来进行访问')
})
02Node.js
代码标准
无分号注意:无分号当使用以下开头( [ ` 最好前面补分号,避免一些问题
` 是 EcmaScript 6 中新增的一种字符串包裹方式,叫做模板字符串,它支持换行和非常方便拼接变量
在 EcmaScript 6 的 ` 字符串中,可以使用 ${} 来拼接、引用变量
return 有两个作用:
1. 方法返回值
2. 代码继续往后执行
art-template 模板引擎
- 安装:
npm install art-template
该命令在哪执行就会把包下载到哪里。默认会下载到 node_modules 目录中
node_modules 不要改,也不支持改。 - 在需要使用的文件模块中加载 art-template
只需要使用 require 方法加载就可以了:require('art-template')
参数中的 art-template 就是你下载的包的名字
也就是说你 isntall 的名字是什么,则你 require 中的就是什么
- 查文档,使用模板引擎的 API
- template.render() 默认读取到的 data 是二进制数据,而模板引擎的 render 方法需要接收的是字符串,所以我们在这里需要把 data 二进制数据转为 字符串 才可以给模板引擎使用
问题:如何生成自动可变的目录
- 如何得到 wwwDir (即自定义的根路径) 目录列表中的文件名和目录名
fs.readdir
- 如何将得到的文件名和目录名替换到 template.html (主页面)中
2.1 在 template.html (主页面)中需要替换的位置预留一个特殊的标记(就像以前使用模板引擎的标记一样)
2.2 根据 files 生成需要的 HTML 内容 - 注意:在浏览器中需要引用 lib/template-web.js 文件
强调:模板引擎不关心你的字符串内容,只关心自己能认识的模板标记语法,例如 {{}}
{{}} 语法被称之为 mustache 语法,八字胡啊。
客户端渲染和服务端渲染
- 服务端渲染即在服务端使用模板引擎
- 服务端渲染和客户端渲染的区别
- 客户端渲染不利于 SEO 搜索引擎优化
- 服务端渲染是可以被爬虫抓取到的,客户端异步渲染是很难被爬虫抓取到的
- 所以你会发现真正的网站既不是纯异步也不是纯服务端渲染出来的,而是两者结合来做的
- 例如京东的商品列表就采用的是服务端渲染,目的了为了 SEO 搜索引擎优化,而它的商品评论列表为了用户体验,而且也不需要 SEO 优化,所以采用是客户端渲染
- 最少两次请求,发起 ajax 在客户端使用模板引擎渲染
- 客户端拿到的就是服务端已经渲染好的
制作留言本
步骤
- / index.html
- 开放 public 目录中的静态资源
当请求 /public/xxx 的时候,读取响应 public 目录中的具体资源 - /post post.html(表单页面)
- /pinglun
4.1 接收表单提交数据
4.2 存储表单提交的数据
4.3 让表单重定向到 /
statusCode
setHeader
主页面
- 处理留言本案例首页数据列表渲染展示
- 处理留言本案例发表留言功能
开放public
路径:如果请求路径是以 /public/ 开头的,则我认为你要获取 public 中的某个资源,所以我们就直接可以把请求路径当作文件路径来直接进行读取
解析路径url
Node 中需要咱们自己动手来解析
- var url = req.url
- 如果是文件,直接读取响应
- 如果是目录,读取渲染目录列表
- 如果目录并且有该目录中有 index.html 则直接渲染目录中的 index.html
- 使用 url.parse 方法将路径解析为一个方便操作的对象,第二个参数为 true 表示直接将查询字符串转为一个对象(通过 query 属性来访问)
- 已经使用 url 模块的 parse 方法把请求路径中的查询字符串给解析成一个对象后
- 获取表单提交的数据 parseObj.query
var parseObj = url.parse(req.url, true)
2. 将当前时间日期添加到数据对象中,然后存储到数组中
3. 让用户重定向跳转到首页 /当用户重新请求 / 的时候,我数组中的数据已经发生变化了,所以用户看到的页面也就变了
- 获取表单提交的数据 parseObj.query
- 服务端这个时候已经把数据存储好了,接下来就是让用户重新请求 / 首页,就可以看到最新的留言内容了
重定向
header('location')
-
301 永久重定向 浏览器会记住
- a.com b.com
- a 浏览器不会请求 a 了
- 直接去跳到 b 了
-
302 临时重定向 浏览器不记忆
- a.com b.com
- a.com 还会请求 a
- a 告诉浏览器你往 b
-
如何通过服务器让客户端重定向?
- 状态码设置为 302 临时重定向
statusCode
2. 在响应头中通过 Location 告诉客户端往哪儿重定向
setHeader
res.statusCode = 302 res.setHeader('Location', '/') res.end()
- 状态码设置为 302 临时重定向
Console(REPL)使用
node回车到类似控制台的执行环境,作用:类似api辅助测试,退出两次ctrl+c