引言
node在前端领域的地位非常重要,退可基于node环境安装依赖(npm install),进可深入node内置模块,搭建web后台服务,提供数据接口,完成独立项目(因为都是用JS写的,语法互通,非常适合前端了解后端,而且天生支持高并发,广泛应用于中小型项目)。(例如12306,沃尔玛,eBay,Paypal,Netflix,腾讯的OA系统)
node的优势
node的诞生就是为了解决高并发问题,因为他是基于JS开发(可以看作是运行在服务器端的JS),而且基于事件驱动和无阻塞,所以非常适合处理并发请求,因此构建在Node上的代理服务器相比其他技术实现(如Ruby)的服务器表现要好得多。
每语言都有自己的优势,相对也有自己的劣势
node的劣势
由于V8引擎有内存设计的限制,32位内存限制为1G,64位环境不到2G,所以如果一次性读取10G数据,是无法实现的。总的来说,对于Nodejs,不擅长的领域在于CPU和内存的编程操作。(因为js为弱类型语言,在js的超集typescript强类型语言出现后,解决了后期维护麻烦的问题)
在实际的开发中,前后端的分离虽然加快了并行开发速度,减轻后台请求压力,提升页面性能,增强代码可维护性等,但前后端经过Ajax等异步请求进行通信,会出现首屏渲染的时间长,不利于搜索引擎利用爬虫解析网站内容(行为逻辑存在了JS中)从而影响网站曝光度的问题,node除了可为前端安装依赖包外,还可搭建一个“服务器”,利用ssr(服务端渲染),与数据后台再进行交互(node服务器作为中间层),解决上述问题。
一些常见的模块
fs文件系统模块
fs模块可以用来操作文件
读取文件内容(readFile)
const fs = require('fs')
// 参数一:必选,字符串,表示文件路径
// 参数二:可选,表示用什么编码格式来读取
// 参数三:必选,文件读取完成后,通过回调拿到的结果
// 回调结果中形参依次为(读取失败的错误信息【无信息返回null】,读取正确时返回的内容【无信息返回undefined】)
fs.readFile('./oculus.txt', 'utf8', (err, dataStr) => {
console.log(err);
console.log('............');
console.log(dataStr);
})
写入文件内容(writeFile)
// 参数一:必选,字符串,表示文件路径
// 参数二:必选,要写入的内容(这会覆盖原来的内容)
// 参数三:可选,表示用什么编码格式来写入
// 参数四:必选,文件读取完成后,通过回调拿到的错误结果,其中形参为(错误信息【无信息返回null】)
let words = '我想写入这句话'
fs.writeFile('./111.txt', words, 'utf8', (err) => {
console.log(err);
})
在上文中,读取文件的路径都为相对路径,对于程序移植性很差,我们就需要动态拼接路径
动态路径(__dirname)
利用node内置变量__dirname找到当前程序运行的绝对路径
路径模块(path)
路径智能拼接(join)
path模块的join方法可以在拼接文件路径时解析文件层级,避免手动拼接出问题
// 拼接路径
const pathStr = path.join('/a', '/b/c', '../', './d', 'g')
console.log(pathStr); // \a\b\d\g
文件名过滤(basename)
// 过滤文件名
const str = '/txttxt/culus.txt'
// 参数一:过滤文件路径,找到文件名
// 参数二:过滤掉文件扩展名
const pathWithoutExt = path.basename(str, '.txt')
console.log(pathWithoutExt); // culus
文件拓展名过滤(extname)
const str = '/txttxt/culus.txt'
// 获取文件拓展名
const extname = path.extname(str)
console.log(extname); // .txt
http模块
创建服务器,接受请求
// 导入http模块
const http = require('http')
// 创建web服务器实例
const server = http.createServer()
// 启动服务器
server.listen(8089, () => {
console.log('server is runing on 127.0.0.1:8089');
})
// 为服务器绑定request事件
// 参数一:服务器接收到客户端的请求,就会调用on方法将请求信息存放在req中
server.on('request', (req, res) => {
// 得到请求地址和请求方法
const info = `请求地址为:${req.url},请求方法是:${req.method}`
console.log(info);
console.log('visit my server');
// 设置请求头的编码格式,防止乱码
res.setHeader('Content-Type', 'text/html; charset=utf-8')
// 响应信息,并结束此次请求的处理过程
res.end(info)
})
浏览器(客户端)默认发起GET请求,并返回客户端的响应信息
服务器接收请求
客户端发起POST请求
服务器接收请求
小贴士(模块加载顺序)
使用require导入自定义模块时,如果省略扩展名,node会按照以下顺序,加载同名文件
- 按照具体的(文件名.扩展名)加载
- 自动补全成.js加载
- 自动补全成.json加载
- 自动补全成.node加载
- 加载失败,报错
引入第三方模块时,如果在require中引入的不是node内置模块,也没有以 './' 或 '../' 开头,node会尝试从依赖包/node_modules中加载第三方模块 例如:C:\a\b\c\main.js文件中,引入require('tool'),实际自动补全路径的顺序为:
- C:\a\b\c\node_modules\tool
- C:\a\b\node_modules\tool
- C:\a\node_modules\tool
- C:\node_modules\tool