node.js
node.js 没有 dom 和 bom 操作
Node.js 是什么
既不是语言,也不是框架,它是一个平台
没有 BOM、DOM
EcmaScript 基本的 JavaScript 语言部分
在 Node 中为 JavaScript 提供了一些服务器级别的 API
node 启动
node index.js
创建 web 服务器
1.加载 http 核心模块
var http = require('http')
2.使用 http.createServer() 方法创建一个 Web 服务器
var server = http.createServer()
3.服务器操作
server.on('request', function () {
console.log('收到客户端的请求了')
})
4.绑定端口号,启动服务器
server.listen(3000, function () {
console.log('服务器启动成功了,可以通过 http://127.0.0.1:3000/ 来进行访问')
})
服务器接收参数
Request 请求对象
请求对象可以用来获取客户端的一些请求信息,例如请求路径
Response 响应对象
响应对象可以用来给客户端发送响应消息
服务器操作
在 http 协议中,Content-Type 就是用来告知对方我给你发送的数据内容是什么类型
// text/plain 就是普通文本
// 如果你发送的是 html 格式的字符串,则也要告诉浏览器我给你发送是 text/html 格式的内容
可以采用读取图片的方式,然后如果文件读取成功的话,end 返回一个(data),data 就是数据
fs.readFile('./resource/ab2.jpg', function (err, data) {
if (err) {
res.setHeader('Content-Type', 'text/plain; charset=utf-8')
res.end('文件读取失败,请稍后重试!')
} else {
res.setHeader('Content-Type', 'image/jpeg')
res.end(data)
}
})
node.js 核心模块
用来获取机器信息的
var os = require('os')
用来操作路径的
var path = require('path')
获取当前机器的 CPU 信息
console.log(os.cpus())
memory 内存
console.log(os.totalmem())
获取一个路径中的扩展名部分
extname extension name
console.log(path.extname('c:/a/b/c/d/hello.txt'))
node.js 理论细节
在 Node 中没有全局作用域的概念
在 Node 中,只能通过 require 方法来加载执行多个 JavaScript 脚本文件
require 加载只能是执行其中的代码,文件与文件之间由于是模块作用域,所以不会有污染的问题
模块完全是封闭的
外部无法访问内部
内部也无法访问外部
模块作用域固然带来了一些好处,可以加载执行多个文件,可以完全避免变量命名冲突污染的问题
但是某些情况下,模块与模块是需要进行通信的
在每个模块中,都提供了一个对象:
exports
该对象默认是一个空对象
你要做的就是把需要被外部访问使用的成员手动的挂载到
exports
接口对象中然后谁来
require
这个模块,谁就可以得到模块内部的exports
接口对象
核心模块
核心模块是由 Node 提供的一个个的具名的模块,它们都有自己特殊的名称标识,例如
fs 文件操作模块
http 网络服务构建模块
os 操作系统信息模块
path 路径处理模块
关于 js 代码是否使用分号
建议如果一行代码是以 (、[、` 开头的,则最好都在其前面补上一个分号。
服务端渲染和客户端渲染的区别
客户端渲染不利于 SEO 搜索引擎优化
服务端渲染是可以被爬虫抓取到的,客户端异步渲染是很难被爬虫抓取到的
所以你会发现真正的网站既不是纯异步也不是纯服务端渲染出来的
而是两者结合来做的
例如京东的商品列表就采用的是服务端渲染,目的了为了 SEO 搜索引擎优化
而它的商品评论列表为了用户体验,而且也不需要 SEO 优化,所以采用是客户端渲染
Express
介绍
第三方 Web 开发框架
高度封装了 http 模块
更加专注于业务,而非底层细节
知其所以然
- 增删改查
- 使用文件来保存数据(锻炼异步编码)
- MongoDB
- (所有方法都封装好了)
使用
- 安装 npm
- 引包
var express = require('express')
- 创建你服务器应用程序
var app = express()
开放资源
只要这样做了,你就可以直接通过 /public/xx 的方式访问 public 目录中的所有资源了
app.use('/public/', express.static('./public/'))
用户访问 public 地址的时候,给他显示 public 接口
get 请求
app.get('/about', function (req, res) {
// 在 Express 中可以直接 req.query 来获取查询字符串参数
console.log(req.query)
res.send('你好,我是 Express!')
})
开启接口
相当于 server.listen
app.listen(3000, function () {
console.log('app is running at port 3000.')
})
使用模板
\1. 安装 express-art-template 和 art-template
\2. 配置 html 表示使用的是 html 结尾的模板才能使用
app.engine('html', require('express-art-template'))
获取表单内容
- 安装 body-parser
2.配置
var bodyParser = require('body-parser')
// 配置模板引擎和 body-parser 一定要在 app.use(router) 挂载路由之前
// parse application/x-www-form-urlencoded
app.use(bodyParser.urlencoded({ extended: false }))
// parse application/json
app.use(bodyParser.json())
异步
一般情况下,把函数作为参数的目的就是为了获取函数内部的异步操作结果
JavaScript 单线程、事件循环
异步操作的函数
setTimeout
readFile
writeFile
ajax
**dirname 和 **filename
动态的获取当前文件或者文件所处目录的绝对路径
用来解决文件操作路劲的相对路径问题
因为在文件操作中,相对路径相对于执行
node
命令所处的目录所以为了尽量避免这个问题,都建议文件操作的相对路劲都转为:动态的绝对路径
方式:
path.join(__dirname, '文件名')
用了这个他就会帮助你获取当前的电脑的绝对路径,避免了相对路径会遇到的问题也不至于会写死
__dirname 是用来获取文件的目录
__filename 可以用来获取当前的文件名
就是专门用来动态的获取当前文件以及文件所属目录的绝对路径
中间件
中间件:处理请求的,本质就是个函数
当请求进来,会从第一个中间件开始进行匹配
- 如果匹配,则进来
如果请求进入中间件之后,没有调用 next 则代码会停在当前中间件
如果调用了 next 则继续向后找到第一个匹配的中间件
- 如果不匹配,则继续判断匹配下一个中间件
不关心请求路径和请求方法的中间件
也就是说任何请求都会进入这个中间件
中间件本身是一个方法,该方法接收三个参数:
Request 请求对象
Response 响应对象
next 下一个中间件
通配
app.use(function (req, res, next) {
console.log(1)
next()
})
以 /a 开头的路径中间件
app.use(‘/a’, function (req, res, next) {
console.log(‘a’)
next()
})
精准匹配
app.get(‘/abc’, function(req, res, next) {
console.log(‘abc’)
next()
})
如果不写 next()就不会继续执行下个中间件 其实之前用的很多插件使用 use 的配置都是采用了中间件,然后 next()到下一个 所以才能使用那些方法
配置错误处理中间件
next(err)
app.use(function (err, req, res, next) {
es.status(500).send(err.message)
})
如果使用中间的 next()里面传递了参数,那么就会直接进入错误处理中间件,这个中间件必须拥有四个参数