基于谷歌V8引擎,运行在服务器端的环境,适合开发I/O密集型应用,解决高并发,基于社交网络的大规模web应用
对比JS和NodeJS
- JS运行在客户端浏览器,存在多个浏览器,存在兼容性;NodeJS运行在服务器端,只有V8引擎一种环境,不存在兼容性问题
- 两者都有内置对象、自定义对象、不同的宿主对象
- JS用于浏览器端的交互效果,NodeJS用于服务器端操作,例如文件操作,数据库操作等
运行JS程序
node 文件名
模块
在nodejs下,每一个文件就是一个独立的模块
nodejs会自动为每一个js文件添加一个匿名函数,所有的代码都包含在这个函数中,匿名函数中有五个参数
- __filename:当前模块的绝对路径+模块名称
- __dirname:当前模块的绝对路径
- require:是一个函数,用来引入其他模块,返回值是引入模块的导出内容
- module:当前模块对象,module.exports:当前模块的导出对象
- exports:module.exports的别名,指向同一个对象
注意:module.exports指向的是一个对象!对象!对象!,但是可以通过赋值修改指向,指向什么就导出什么
(function (exports, require, module, __filename, __dirname) {
// exports实际是module.exports
console.log("exports:", exports);
console.log("__dirname:", __dirname);
console.log("__filename:", __filename);
console.log("require:", require);
console.log("module:", module);
})(exports, require, module, __filename, __dirname);
module.exports和require
module.exports:当前模块的导出对象
// 01.js
var sum = function (a, b) {
return a + b;
}
module.exports.sum = sum;
require:是一个函数,用来引入其他模块,返回值是引入模块的导出内容
// 引入同级目录下的文件,路径 './文件名'
var sum = require('./01.js');
console.log(sum);
module.exports和exports
exports:module.exports的别名,指向同一个对象
exports是在初始化的时候跟module.exports指向同一个对象
但是module.exports才是真正的导出对象
模块分类
文件模块
以路径开头:require('./xxx.js'); ,常用于引入自定义的模块
不以路径开头:require('url'); ,常用于引入官方提供的核心模块
目录模块
以路径开头:require('./xxx'); ,去xxx目录下寻找package.json中的main属性对应的文件,如果没有就使用index.js
不以路径开头:require('xxx'); ,到当前目录下的node_modules中寻找xxx目录,如果找不到,会一直向上层目录寻找,直到顶级目录,常用于第三方模块的引入
包和NPM
包(package):就是一个目录模块
NPM:用于管理包的工具
查看npm版本
npm version
初始化一个package.json文件,项目说明文件,会记录安装的包的相关信息
npm init -y
自动下载包,并添加到node_modules目录中,install可简写成i
npm install 包名称
卸载包
npm uninstall 包名称
自动安装package.json中记录的包
npm install
安装包到全局,-global代表全局,可简写成-g
npm install -global 包名称
查看当前镜像地址
npm get registry
切换为淘宝镜像
npm config set registry http://registry.npm.taobao.org/
切换为npm镜像
npm config set registry https://registry.npmjs.org/
快捷命令
npm run 在scripts中配置的npm命令缩写
简述常见的package.json配置项
- name: 这个很好理解,就是package的名称
- version: package的版本
- desription:包的描述。开发组件库时必需,简明的向库的使用者介绍这个库是干嘛的。
- keywords:关键词。对这个npm包的介绍。组件库必需,便于使用者在npm中搜索。
- author:项目的作者。可以为字符串,对象。
- main:代码入口。
- scripts:指定了运行脚本命令的npm命令行缩写。
- dependencies:运行依赖。通过npm install --save安装的包会出现在这里。
- devDependencies:开发依赖。通过npm run install --save-dev安装的包会出现在这里
url模块
url模块用来处理url
const url = require('url');
// parse() 将URL解析为对象
// format() 将对象格式化为URL
let str = 'http://www.baidu.com:80/users/login?uname=tom&upwd=123456';
let obj = url.parse(str);
console.log(obj);
let str1 = url.format(obj);
console.log(str1);
querystring模块
querystring模块用来处理查询字符串
const url = require('url');
const querystr = require('querystring');
// parse() 将查询字符串解析为对象
// stringify() 将对象格式化为查询字符串
let str = 'http://www.baidu.com:80/users/login?uname=tom&upwd=123456';
let obj = url.parse(str);
console.log(obj);
let str1 = url.format(obj);
console.log(str1);
let str2 = obj.query;
let obj2 = querystr.parse(str2);
console.log(obj2,obj2.uname);
let str3 = querystr.stringify(obj2);
console.log(str3);
fs模块
fs模块用来处理文件系统
const fs = require('fs');
//创建文件夹 有异步方法
fs.mkdirSync('mydir');
//删除文件夹 有异步方法
fs.rmdirSync('mydir');
//读取文件夹内容 有异步方法
let arr = fs.readdirSync('mydir');
console.log(arr);
//判断文件或文件夹是否存在 异步方法已废弃
console.log(fs.existsSync('mydir'));
//查看文件或文件夹状态 有同步方法
fs.stat('mydir',(err,res)=>{
if(err) throw err;
console.log(res,res.isFile(),res.isDirectory());
});
//清空写入 如果没有文件则创建文件
fs.writeFileSync('mydir/a.txt','hello.com\r\n');
//追加写入 如果没有文件则创建文件
fs.appendFileSync('mydir/a.txt','append.com\r\n');
//读取文件
let str = fs.readFileSync('mydir/a.txt');
console.log(str.toString());
//删除文件
fs.unlinkSync('mydir/a.txt');
文件流
const fs = require('fs');
console.time('read');
let resr = fs.readFileSync('VSCodeUserSetup-x64-1.42.1.exe');
fs.writeFileSync('1.exe', resr);
console.timeEnd('read');
console.time('create');
let crer = fs.createReadStream('VSCodeUserSetup-x64-1.42.1.exe'); // 读取流
let crew = fs.createWriteStream('2.exe'); // 写入流
crer.pipe(crew);
console.timeEnd('create');
fs.unlinkSync('1.exe');
fs.unlinkSync('2.exe');
HTTP模块
NodeJS提供了http模块,http模块主要用于搭建HTTP服务端和客户端,使用HTTP服务器或客户端功能必须调用http模块
http协议:浏览器和web服务器之间的协议
通用头信息
- Request URL:向服务器请求的内容有哪些
- Request Method:请求的方法 get/post
- Remote Address:请求的服务器IP地址及端口号**
- Status Code:响应的状态码
响应头信息
- Location:跳转的
- URLContent-Type:响应的文件类型
- Content-Length:内容的长度(字节)
- Connection:建立连接的方式 keep-alive持久连接
- Content-Encoding:文件的压缩类型 gzip
请求头信息
- Host:浏览器告诉服务器,请求的是哪台主机
- Connection: keep-alive:浏览器告诉服务器,请开启持久连接
- Accept-Encoding: gzip:浏览器告诉服务器,我这个浏览器可以接收的压缩文件类型
- Accept-Language: zh-CN,zh;q=0.9,en;q=0.8:浏览器告诉服务器,我这个浏览器可以接收的自然语言的类型
- User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/66.0.3359.139 Safari/537.36:浏览器告诉服务器,当前浏览器及其操作的系统的基本信息
请求主体
浏览器端传递的数据,formdata (post/put向服务器发送的参数)
app
HTTP 客户端,发送get请
const http = require('http');
// url:请求地址
// res:响应对象
http.get(url,(res) => {
// res.statusCode:响应状态码
console.log(res.statusCode);
// res.on();监听服务器端响应的数据
// chunk数据段,格式为buffer
res.on('data',(chunk)=>{
console.log(chunk.toString());
});
});
HTTP 服务端, 接收请求
const http = require('http');
//创建web服务器
let app = http.createServer();
//设置端口
app.listen(8088);
//监听浏览器请求,使用回调函数处理请求
//req 请求的对象
//res 响应的对象
app.on('request',(req,res)=>{
//req.url 请求的URL
//req.method 请求的方法
console.log(req.url,req.method);
//res.writeHead(状态码,头信息对象) 设置响应的状态码和头信息
res.writeHead(200,{ 'Content-type' : 'text/html;charset=utf-8' });
//res.write() 设置响应的内容
res.write('hello world!');
//res.end() 结束并发送响应
res.end();
});
设置响应的状态码和头信息
返回html页面
res.writeHead(200,{ 'Content-type' : 'text/html;charset=utf-8' });
重定向
res.writeHead(302,{ Location : 'http://www.baidu.com' });
压缩格式
res.writeHead(200 ,{ 'Content-Encoding' : 'gzip' });
404
res.writeHead(404);
zlib模块
专门用于压缩的模块
const http = require('http');
const fs = require('fs');
const zlib = require('zlib');
let app = http.createServer();
app.listen(8088);
app.on('request',(req,res)=>{
//告诉浏览器响应的压缩类型
res.writeHead(200,{'Content-Encoding':'gzip','Content-type' : 'text/html;charset=utf-8'})
let gzip=zlib.createGzip()//创建gzip压缩
//创建可读取的文件流添加到压缩,直接把压缩响应给浏览器
fs.createReadStream('filename.html').pipe(gzip).pipe(res);
// res.writeHead(200, {'Content-Type': 'image/png','Content-Encoding' : 'gzip'});
// let gzip = zlib.createGzip();
// fs.createReadStream( 'timg.jpg' ).pipe(gzip).pipe(res);
});
全局对象
- 在交互模式下,声明的变量和函数都是全局作用域下的,可以使用global访问;
var a = 1;
global.a
- 在脚本模式下,声明的变量和函数都是局部作用域下的,不能使用global访问;
var a = 1;
let b = 2;
c = 3;
// 在脚本模式下,声明的变量和函数都是局部作用域下的,不能使用global访问
// 没有通过关键字声明而直接使用的变量可以通过global访问
console.log(global.a,global.b,global.c);
function fun() {
this.num = 10;
// node中全局函数中的this指向global
// console.log(this);
// console.log(global);
// console.log(this == global);
}
fun();
console.log(global.num);
- 在脚本模式下,声明的变量和函数都是局部作用域下的,不能使用global访问;
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script>
var a = 1;
let b = 2;
c = 3;
console.log(window.a,window.b,window.c);
</script>
</head>
<body>
</body>
</html>
this对象指向
node中全局函数中的this指向global
函数的外面this指向的是一个空对象{},而在函数内部的this没有指定的执行上下文,所以它指向了global对象
console.log(global);
// node中的this不是指向global,而是指向module.exprots
console.log(this);
console.log(module.exports);
// true
console.log(this == module.exports);
console.log('--------');
function fun() {
this.num = 10;
// node中全局函数中的this指向global
console.log(this);
console.log(global);
console.log(this == global);
}
fun();
node运行的文件都被包裹在一个匿名函数中
(function (exports, require, module, __filename, __dirname) {
// exports实际是module.exports
console.log("exports:", exports);
console.log("__dirname:", __dirname);
console.log("__filename:", __filename);
console.log("require:", require);
console.log("module:", module);
})(exports, require, module, __filename, __dirname);
process
// process.nextTick不属于定时器,但是执行如果单独使用,执行时机和setImmediate类似
// setImmediate是放在事件队里最顶端,process.nextTick是在主程序最后执行
process.nextTick(function () {
console.log('这里是process立即执行');
});
console.log('---这里是js---');
nvm
nvm是Node.js的版本管理器
https://github.com/nvm-sh/nvm
windows版本:https://github.com/coreybutler/nvm-windows
查看哪些nodejs版本可以安装
nvm list available
查看哪些版本已经安装
nvm list
*代表当前使用的版本
18.15.0
* 16.16.0
14.20.0
12.16.3
安装nodejs
nvm install 版本号
切换版本
nvm use 版本号
nrm
nrm是npm镜像地址管理器
https://github.com/Pana/nrm
安装
npm install -g nrm
查看镜像
nrm ls
*代表当前使用的镜像地址
* npm ---------- https://registry.npmjs.org/
yarn --------- https://registry.yarnpkg.com/
tencent ------ https://mirrors.cloud.tencent.com/npm/
cnpm --------- https://r.cnpmjs.org/
taobao ------- https://registry.npmmirror.com/
npmMirror ---- https://skimdb.npmjs.com/registry/
切换镜像
nrm use 镜像名称