node
// 既不是语言,也不是框架,它是一个平台
// Node.js中的JavaScript
// 没有BOM、DOM
// EcmaScript基本的JavaScript语言部分
// 在Node中为JavaScript提供了一些服务器级别的API
// 文件操作的能力
// http服务的能力
运行node
console.log('nodejs')
// 控制台
node index.js
读取/写入文件
// 浏览器中的JavaScript没有文件操作能力
// 但Node中的JavaScript具有文件操作能力
// fs是file-system简写 文件系统的意思
// 在Node中如果要进行文件操作 必须引入fs核心模块
var fs = require('fs')
// path 读取的文件路径
// callback 回调函数
fs.readFile(path, callback)
// err 错误对象
// data Buffer类数据
// JavaScript 语言自身只有字符串数据类型 没有二进制数据类型
// 处理像TCP流或文件流时 须使用到二进制数据
// Node.js定义了Buffer类用来创建一个专门存放二进制数据的缓存区
// 成功 err null data Buffer类数据
// 失败 err 错误对象 data undefined
// toString方法转Buffer类数据
fs.readFile(path, (err, data) => {
if (err) {
return
}
console.log(data.toString())
});
// 指定编码类型
fs.readFile(path, 'UTF-8', (err, data) => {
if (err) {
return
}
console.log(data)
});
// path 写入的文件路径及文件名后缀
// data写入内容
// callback 回调函数
fs.writeFile(path, data, callback);
// 成功 err null
// 失败 err 错误对象
fs.writeFile(path, data, (err) => {
if (err) {
return
}
console.log('文件已被写入');
});
http服务
// http核心模块 创建编写服务器
var http = require('http')
// 创建Web服务器
var server = http.createServer()
// 注册request请求事件
// 客户端请求过来自动触发服务器的request请求事件
// 执行回调处理函数
server.on('request', function () {
console.log('收到客户端的请求了')
})
// 绑定端口号 启动服务器
server.listen(3000, function () {
console.log('服务器启动成功了 通过 http://127.0.0.1:3000/ 来进行访问')
})
请求回调处理函数
// request 请求对象
// 用来获取客户端的请求信息
// response 响应对象
// 用来给客户端发送响应消息
server.on('request', function (request, response) {
// 响应内容只能是二进制数据或者字符串
console.log('收到客户端的请求了 请求路径是:' + request.url)
response.write('hello')
response.write('nodejs')
// 通知客户端 响应结束
response.end()
// or
// res.end('hello nodejs')
})
node中核心模块
fs // 文件操作模块
http // 网络服务构建模块
os // 操作系统信息模块
path // 路径处理模块
os.cpus() // 当前机器的CPU信息
os.totalmem() // memory内存
path.extname('c:/xxx/hello.txt') // 路径中的扩展名部分 extname extension name
ip地址和端口号
// ip用来定位计算机
// 端口号定位具体的应用程序
// 需要联网通信的应用程序都会占用一个端口号
Content-Type
// 服务端默认发送的数据是utf8编码内容
// 但浏览器不知道是utf8编码的内容
// 浏览器在不知道服务器响应内容的编码的情况下
// 按照当前操作系统的默认编码去解析
// 中文操作系统默认是gbk
// 解决方法就是正确的告诉浏览器我给你发送的内容是什么编码的
// 在http协议中Content-Type就是用来响应浏览器
// 发送的数据内容类型
// 文本类型的数据 最好都加上编码 目的是为了防止中文解析乱码问题
// 不指定类型 浏览器按照gbk编码解析
response.end('<a href="">链接</a>')
// 指定编码类型utf8
// 控制台Response Header
// Content-Type: text/html; charset=utf-8
// text/plain 普通文本
// text/html html格式字符串
response.setHeader('Content-Type', 'text/html; charset=utf-8')
response.end('<a href="">链接</a>')
Response返回页面
fs.readFile(path, 'UTF-8', function (err, data) {
if (err) {
res.setHeader('Content-Type', 'text/plain; charset=utf-8')
res.end('文件读取失败')
} else {
res.setHeader('Content-Type', 'text/html; charset=utf-8')
res.end(data)
}
})
读取文件夹列表
// dirPath 读取的文件夹路径
// callback 回调函数
fs.readdir(dirPath, callback}
// err 错误对象
// files 文件夹下文件数组
// 成功 err null files 文件数组
// 失败 err 错误对象 files undefined
fs.readFile(dirPath, (err, files) => {
if (err) {
return
}
console.log(files)
})
返回文件夹下文件/读取目录
// index.html
<ul>^^_^^</ul>
// index.js
fs.readdir('./dir', function (err, files) {
if (err) {
response.end('404 not found...')
} else {
fs.readFile('./index.html', 'UTF-8', function (err, data) {
if (err) {
response.end('404 not found...')
} else {
response.end(data.replace('^^_^^', files.reduce((pre, cur) => pre += `<li>${cur}</li>`, '')))
}
})
}
})
服务端/客户端渲染
// 服务端渲染
// 只请求一次页面和数据
// 服务端读取html页面
// 在发送客户端之前 模板引擎渲染
// 渲染结果 = template.rendar(模板字符串, { 解析替换对象 })
// response.end(渲染结果)
// 客户端渲染
// 第一次请求页面
// 第二次请求动态数据
// 客户端获取的页面发起ajax请求获取动态数据
// 模板引擎渲染
// 客户端渲染不利于SEO搜索引擎优化
// 服务端渲染是可以被爬虫抓取到的 客户端异步渲染是很难被爬虫抓取到的
// 商品列表就采用服务端渲染 目的了为了SEO搜索引擎优化
// 商品评论列表为了用户体验 也不需要SEO优化 采用是客户端渲染
url模块
// 请求参数
var url = require('url')
url.parse('/pinglun?name=zs&age=18', true) // { name: zs, age: 18}
模块系统
// Node中每个模块内部都有一个自己的module对象
// module对象含有exports属性 也是对象
// 需要对外导出成员 则挂载到module.exports中
// 挂载xxx module.exports.xxx = xxx
// 对于变量多的情况 显得繁琐
// Node为了简化操作 提供exports对象 指向module.exports
// 则exports.xxx = xxx
// exports只是module.exports的引用
// 改变exports引用 不会影响module.exports的挂载
// 每个模块末尾相当于有一句
var module = {
exports: {
xxx: xxx
}
}
var exports = module.exports
// 导出单个成员
module.exports = function (){...}
// 导出多个
exports.xxx = xxx
module.exports.xxx = xxx
module.exports = {
xxx: xxx,
...
}
require标识符
// 模块分类
// 路径形式模块
./ // 当前目录不可省略
../ // 上一级目录不可省略
/xxx // 几乎不用
// 首位/表示当前文件模块所属磁盘根路径
// .js 后缀名可以省略
// 核心模块
// fs http url path
// 第三方模块
// 模块查找机制
// 优先从缓存加载
// 核心模块
// 路径形式的文件模块
// 第三方模块
// node_modules/art-template
// node_modules/art-template/package.json
// node_modules/art-template/package.json main
// index.js 备选项
// 进入上一级目录找 node_modules
// 按照这个规则依次往上找,直到磁盘根目录还找不到
// 最后报错:Can not find moudle xxx
// 一个项目有且仅有一个 node_modules 而且是存放到项目的根目录
重定向
// 通过服务器让客户端重定向
// 状态码设置为302临时重定向
// 在响应头中通过Location告诉客户端往哪儿重定向
// 如果客户端发现收到服务器的响应的状态码是302就会自动去响应头中找
// Location然后对该地址发起新的请求
// 301 永久重定向 浏览器会记住
// 再次请求页面 浏览器直接跳转
// 302 临时重定向 浏览器不记忆
// 再次请求页面 浏览器还会请求
res.statusCode = 302
res.setHeader('Location', '/')
path核心模块
// 路径相关信息
path.parse('c:/xxx/path.html')
{
root:'c:/', // 根路径
dir:'c:/xxx', // 目录
base:'path.html', // 含后缀文件名
ext:'.html', // 后缀名
name:'path' // 文件名
}
// 目录名
path.dirname('c:/xxx/path.html') // c:/xxx
// 路径拼接
// 避免手动拼接错误
path.join('c:/xxx','path.html') // c:/xxx/path.html
Node其他成员
// 当前文件模块所属目录的绝对路径
__dirname
// 当前文件绝对路径
__filename
// Node中相对路径是相对于执行node命令所处的路径
├── demo
│ └── a
│ │ └── index.js // fs.readFile('./c.txt')
│ │ └── c.txt
│ └── b
│ └── c.txt
// 执行c:/xxx/demo node a/index.js
// readFile文件路径为 c:/xxx/demo/c.txt
// 执行c:/xxx/demo/a node index.js
// readFile文件路径为 c:/xxx/demo/a/c.txt
// 故Node中文件操作不适用相对路径 使用绝对路径
// fs.readFile(__dirname + '/c.txt')