提示:Node.js 是一个开源与跨平台的JavaScript
运行时环境。它是在浏览器外运行,它是一个事件驱动异步I/O单进程的服务端JS环境,基于Google的V8引擎,V8引擎执行Javascript的速度非常快,性能非常好。
注意:
DOM 和 BOM 等浏览器内置 API
。作为你进击全栈工程师的开始怎么样?
官网参见详解:
node官网
node中文网
node.js社区
Chrome V8
引擎的 JavaScript
运行环境。事件驱动
、非阻塞式 I/O 的模型
,使其轻量又高效。简单的说 Node.js 就是运行在服务端的 JavaScript。
- V8引擎本身就是用于Chrome浏览器的JS解释部分。但是Ryan Dahl,把这个V8引擎搬到了服务器上,用于做服务器的软件。
- Node.js是一个让JavaScript运行在服务器端的开发平台,它让JavaScript的触角伸到了服务器端。
- Node.js不是一种独立的语言,与PHP、JSP、Python、Perl、Ruby的“既是语言,也是平台”不同,Node.js使用JavaScript进行编程,运行在JavaScript引擎上(V8)。
- 与PHP、JSP、.net等相比(PHP、JSP、.net都需要运行在服务器程序上,Apache、Nginx、Tomcat、IIS。),Node.js跳过了Apache、Naginx、Tomcat、IIS等HTTP服务器,它自己不用建设在任何服务器软件之上。
在Java、PHP或者.net等服务器端语言中,会为每一个客户端连接创建一个新的线程。而每个线程需要耗费大约2MB内存。也就是说,理论上,一个8GB内存的服务器可以同时连接的最大用户数为4000个左右。要让Web应用程序支持更多的用户,就需要增加服务器的数量,而Web应用程序的硬件成本当然就上升了
Node.js不为每个客户连接创建一个新的线程,而仅仅使用一个线程。当有用户连接了,就触发一个内部事件,通过非阻塞I/O、事件驱动机制,让Node.js程序宏观上也是并行的。使用Node.js,一个8GB内存的服务器,可以同时处理超过4万用户的连接。`
注:Node.js是一个让JavaScript运行在服务器端的开发平台,所以必须首先在本机安装Node.js环境
NodeJs基于Commonjs模块化开发的规范,它定义一个JS文件就称之为一个模块,(模块化开发,能拆就拆)
在 node 的开发过程中
我们是把每一个功能独立做成一个模块
然后在使用 导入导出 的方式把他们关联在一起
node的模块类型:
内置模块:安装好nodeJS后可以直接使用的模块,也被称之为核心模块
三方模块:需要通过npm/yarn进行安装的模块
自定义模块:开发者自己写的模块,称之为自定义模块
// 导出(自己定义模块的时候)
module.exports / exports
// 导入
require("module_name")
msi下载好的东西,是一个安装包,需要我们手动进行,下一步下一步的安装 - 注意:选择安装文件,nodejs的安装路径不要包含中文
。(**推荐此方式**
)
zip下载好的东西,是一个压缩文件,解压后,是一个文件夹,这个文件夹就是安装目录,需要手动进行一丢丢的配置。(我们需要自己配置**环境变量**
才可以使用)
检查node是否安装成功:
win+r弹出运行窗口
输入cmd
命令行窗口打开后输入:
node -v
出现版本号即为安装成功
如果需要让node运行JavaScript文件,则按照以下语法执行(该操作需要在cmd/命令行/终端/小黑窗
中运行):
node 文件路径/js文件
1. 查看当前目录下所有文件
$ dir
2. 以树状结构展示当前目录下的所有文件及子目录下的所有文件
$ tree
3. 进入当前目录下的某一个目录
$ cd 文件夹名称
4. 返回上一级目录
$ cd ..
5. 切换盘符
$ 盘符:
$ d:
1. 创建文件夹
# 表示在当前目录下创建一个叫做 test 的文件夹
$ md test //或者 mkdir test
2. 移除文件夹
# 表示移除当前文件夹下的 test 文件夹
$ rd test //或者 rmdir test
3. 复制文件夹
# 表示复制一份 test 文件夹起名为 test2
$ xcopy test test2
4. 创建文件
# 表示在当前目录下创建一个叫做 index.js 的文件
$ type nul> index.js
5. 拷贝一份文件
# 表示复制一份 index.js 文件起名为 ceshi.js
$ copy index.js ceshi.js
6. 向文件中写入内容
# 表示向 index.js 中写入一段文本 console.log('hello world')
$ echo console.log("hello world") > index.js
7. 查看文件内的文本内容
# 表示查看 index.js 文件中的文本内容是什么
$ type index.js
8. 给文件或者目录重命名
# 表示把 index.js 更名为 abc.js
$ ren index.js abc.js
9. 删除文件
# 表示把当前目录下的 index.js 删除
$ del index.js
10. 移动文件或文件夹
# 表示把当前目录下的 index.js 文件移动到当前目录下的 a 文件夹下
$ move index.js a
1. 清屏
# 表示把当前屏幕的所有内容都清除
$ cls
2. 查看当前电脑 IP 信息
# 表示查看当前电脑的 IP 信息
$ ipconfig
3. 测试某一个链接地址的网速
# 表示查看访问 百度 网站的速度
$ ping www.baidu.com
4. 查看电脑信息
# 表示查看当前电脑的信息
$ systeminfo
5. 退出cmd窗口
# 表示退出cmd命令提示符窗口
$ exit
全局变量的宿主(类似于浏览器js中的window对象)
,这是一个特殊的对象,称为全局对象(Global Object),它及其所有属性都可以在程序的任何地方访问
导入
require
来导入一个文件// 我是 index.js 文件
require('./a.js')
console.log('我是 index.js 文件')
- 当我在命令行运行 `index.js` 文件的时候
- 首先会把 `a.js` 文件运行一遍
- 然后再继续执行我自己文件内部的代码
// a 接受到的内容就是 a.js 这个文件导出的内容
// 如果 a.js 文件中什么都没有导出,那么接受到的就是一个 空对象
const a = require('./a.js')
导出
// 我是 a.js
// 每一个 js 文件都会有一个对象叫做 module
// 在 module 里面有一个成员,叫做 exports
// 每一个 js 文件会默认把 module.exports 导出
// 也就是说,我们向 module.exports 中添加什么内容
// 那么就会导出什么内容
module.exports.name = 'Jack'
module.exports.age = 18
// 我是 index.js
const a = require('./a.js')
console.log(a) // { name: 'Jack', age: 18 }
更多内置模块及常用内置模块
的更多API用法,可以参考:http://nodejs.cn/api/
operation system
)模块提供了与操作系统相关的实用方法和属性。const os = require('os') // 先导入os模块
// 换行符
os.EOL //根据操作系统生成对应的换行符 window \r\n,linux下面 \n
// cpu相关信息
os.cpus()
// 总内存大小 (单位 字节)
os.totalmem()
// 空余内存大小 (单位 字节)
os.freemem()
// 主机名
os.hostname()
// 系统类型
os.type()
// ...
const path = require('path')
// 获取路径最后一部内容,一般用它来获取文件名称
path.basename('c:/a/b/c/d.html') // d.html
// 获取目录名,路径最后分隔符部分被忽略
path.dirname('c:/a/b/c/d.html') // c:/a/b/c
// 获取路径中文件扩展名(后缀)
path.extname('c:/a/b/c/d.html') // .html
// 给定的路径连接在一起
path.join('/a', 'b', 'c') // /a/b/c
// resolve:模拟cd(切换目录)操作同时拼接路径
console.log(path.resolve("a", "b", "c"));
console.log(path.resolve("a", "../b", "c"));
console.log(path.resolve("/a", "b", "c"));
// ...
const url = require('url');
const href = 'http://www.xxx.com:8080/pathname?id=100#bbb'
// 解析网址,返回Url对象
// 参2 如果为true 则 query获取得到的为对象形式
url.parse(href,true)
//以一种 Web 浏览器解析超链接的方式把一个目标 URL 解析成相对于一个基础 URL。
url.resolve('https://lynnn.cn/foo/bar','bar')
const querystring = require('querystring')
//用于get形式传过来的参数
// query字符串转为对象
querystring.parse('foo=bar&abc=xyz')
querystring.decode('foo=bar&abc=xyz')
// 对象转为query字符串
querystring.stringify({ foo: 'bar',abc: 'xyz'})
querystring.encode({ foo: 'bar',abc: 'xyz'})
注意:fs模块提供了2大类api方法
- 同步操作
- 异步操作(回调函数,套娃行为)
后续写代码的时候有2个方案,一个是使用之前套娃式的写法,二是使用同步的api去实现操作。
const fs = require('fs')
// 写入数据(覆盖),追加写使用 fs.appendFile (追加)
fs.writeFile(文件路径,待写入的数据,err => {})
// 读取文件中数据
fs.readFile(文件路径, 'utf8’,(err,data) => {})
// (同步)检查文件是否存在 返回true/false
// async:异步
// sync:同步
let ret = fs.existsSync(path)
// 获取文件信息(异步)
fs.stat(文件,(err,stats) => {
stats.isDirectory() // 是否是目录
stats.isFile() // 是否为文件
stats.size // 文件大小(以字节为单位)
})
// 删除文件(异步)
fs.unlink(文件路径,err => {})
web服务器
的相关内容。Web服务器一般指的是网站服务器(服务器:给用户提供服务的机器就是服务器),是指驻留因特网上某一台或N台计算机的程序,可以处理浏览器等Web客户端的请求并返回相应响应,在服务器上还需要安装服务器软件,目前最主流的三个Web服务器软件是Apache、 Nginx 、IIS。
-DNS服务器:动态域名解析系统,作用将域名转化成IP地址
ip地址:ip地址有v4和v6之分,IP地址就是互联网上每台计算机/电子设备的唯一地址,因此IP地址具有唯一性。在开发期间,自己的电脑既是一台服务器,也是一个客户端,可以在本机浏览器中输入127.0.0.1进行访问。(IP地址分为公有【用于接入互联网】和私有【组织单元内部的网络,例如:商场、学校、医院、企业等】)
域名:尽管 IP地址能够唯一地标记网络上的计算机,但IP地址是一长串数字,不直观,而且不便于记忆,于是人们又发明了另一套字符型的地址方案,叫域名地址。IP地址和域名是一一对应的关系,这份对应关系存放在一种叫做域名服务器(DNS)的电脑中。在开发测试期间,127.0.0.1 对应的域名是 localhost。
本地如果localhost无法使用,则是因为本机中的hosts文件中没有匹配上ip地址:
hosts文件是本地机器的一个域名与ip地址映射关系的文件,充当了dns的作用。
网络上的计算机之间交换信息,就像我们说话用某种语言一样,在网络上的各台计算机之间也有一种语言,这就是网络协议,不同的计算机之间必须使用相同的网络协议才能进行通信。如:TCP、UDP、HTTP、FTP等等。
服务器的端口号就像是现实生活中的门牌号一样。通过门牌号,外卖员就可以准确把外卖送到你的手中。同样的道理,在一台电脑中,可以运行N多个web 服务。每个 web 服务都对应一个唯一的端口号(
0-65535,2^16
,常见的端口号别占用:20,21,22,25,80,443,3306,3389,11211,27017....
)。客户端发送过来的网络请求,通过端口号,可以被准确地交给对应的 web 服务进行处理。
注:服务器上的端口号是不可以重复的,必须是独一无二。http服务默认端口号为80,https的端口号默认是443。
扩展:计算机的位数,32位和64位
32位和64位指的是计算机的cpu架构,架构对于计算机有什么影响呢?
最大的影响支持的操作系统的位数,还有影响计算机能够识别的最大内存数量。
32位系统最大能够识别2^32b的内存,理论上是4G,但是实际往往比4G小,大概在3.5-3.9之间。
64位系统最大能够识别2^64b的内存。
NodeJs是通过官方提供的http模块
来创建 web服务器的模块。通过几行简单的代码,就能轻松的手写一个web服务,从而对外提供 web 服务
。
通过下面四个步骤,即可简单创建一个服务器
//1、 导入http模块
const http = require('http')
//2、 创建web服务对象实例
const server = http.createServer()
//3、 绑定监听客户端请求事件request
// on方法做事件监听
server.on('request', (request, response) => {})
// request: 接受客户端请求对象,它包含了与客户端相关的数据和属性
// request.url 客户端请求的uri地址
// request.method 客户端请求的方式 get或post
// request.headers 客户端请求头信息(对象)
// ....
// response:服务器对客户端的响应对象
// 设置响应头信息 ,用于响应时有中文时乱码解决处理
// response.setHeader('content-type', 'text/html;charset=utf-8')
// 设置状态码(常见的HTTP状态码有:200,404,301、302、304、403、401、405、500,502)
// response.statusCode = 200(默认是200)
// 向客户端发送响应数据,并结束本次请求的处理过程
// response.end('hello world')
//4、 启动服务
server.listen(8080, () => {
console.log('服务已启动')
// http://127.0.0.1:8080 即可访问
})
案例:手写一个服务器软件,启动后要求用户访问根“/”输出hello world
,用户访问/html5
输出hello h5
。
// 1. 导入http模块
const http = require("http");
// 2. 创建web服务实例
const server = http.createServer();
// 3. 监听request请求
server.on("request", (req, res) => {
// 输出hello world
// res.end("hello world");
if (req.url === "/") {
res.end("hello world");
}
if (req.url === "/html5") {
res.end("hello h5");
}
});
// 4. 启动服务
server.listen(8080, () => {
// 仅是提示作用,可以不写,但是建议写
console.log("server is running at http://127.0.0.1:8080");
});
静态资源:常见的有html、css、js、图片、音频、视频
等
静态资源服务器:专门保存上述静态资源的服务器,称之为静态资源服务器。
实现思路
客户端请求的每个资源uri地址
,作为在本机服务器指定目录中的文件。通过相关模块进行读取文件
中数据
进行响应给客户端,从而实现静态服务器。
需求:使用nodejs的http模块创建静态资源服务器,专门存放静态资源展示2张图片
// 创建服务器有以下几步:
// a. 导入
const http = require("http");
const path = require("path");
const fs = require("fs");
// b. 创建web实例
const server = http.createServer();
// c. 监听request事件
server.on("request", (req, res) => {
// 获取当前用户访问的资源路径
let uri = req.url;
// 由于“/”没有实体资源,需要将“/”做处理,如果访问“/”则让其对应访问“/index.html”
if (uri == "/") {
uri = "/index.html";
}
// 默认情况下,浏览器在第一次请求网站的时候会访问“/favicon.ico”图标文件,如果没有也会出现404
// 如果需要解决这个问题,则有3种方式:
// 方式1:去找个ico文件,存放在静态资源的public目录下,命名为“favicon.ico”
// 方式2:在处理的时候忽略“/favicon.ico”文件的处理,也就是下面的加了判断的写法
// 方式3:不管,不用处理,其不影响页面的显示
if(uri != '/favicon.ico'){
// 读取文件(fs模块),将内容返回给用户(res.end)
let filename = path.join("public", uri);
// 判断文件是否存在
if (fs.existsSync(filename)) {
fs.readFile(filename, (err, data) => {
if (!err) {
// ok
res.end(data);
} else {
// 不ok
res.setHeader("Content-Type", "text/html;charset=utf-8");
res.statusCode = 500;
res.end("请求资源出现错误。。。");
}
});
} else {
res.setHeader("Content-Type", "text/html;charset=utf-8");
res.statusCode = 404;
res.end("你要找的资源失踪了。。。");
}
}
});
// d. 监听端口,启动服务
server.listen(8080, () => {
console.log("server is running at http://127.0.0.1:8080");
});
// 导入
const http = require('http');
const url = require('url');
// 创建实例&监听request事件&监听端口
http.createServer((req, res) => {
// 之前第3步中的回调函数
// 获取地址栏中 query数据
let { query } = url.parse(req.url, true);
console.log(query);
}).listen(8080)
req对象的data事件
(接收请求提交过来的数据的)来获取客户端发送到服务器的数据
。如果数据量比较大,无法一次性发送完毕
,则客户端会把数据切割后分批次发送给服务器
。所以data事件可能会被触发多次,每次触发data事件时,收到的数据只是全部数据的一部分,因此需要做数据的拼接
才能得到完整的数据:const http = require('http');
const queryString = require('querystring');
http.createServer((req, res) => {
let arr = [];
// 数据接受中
req.on('data', buffer => {
arr.push(buffer);
});
// 数据传输结束了
req.on('end', () => {
// 拼接接受到的所有数据
let buffer = Buffer.concat(arr);
let post = queryString.parse(buffer.toString())
console.log(post);
});
}).listen(8080)
Postman
模拟客户端post请求JS环境
。内置插件
能使我们在学习其他第三方插件时更得心应手
。你
有所帮助。