1. NodeJS简介
1) 什么是JavaScript?
javascript是一门运行在浏览器端的脚本语言,用来做客户端页面的交互。
2) JavaScript的运行环境呢?
故名思义:他的运行环境就是浏览器,但是真的是这样的吗?其实不然,他的真正运行环境其实是运行在浏览器内核中的js引擎。为什么是这样的了?因为通俗来讲浏览器的作用就是用来浏览网页的,我们在浏览器除了执行js外还能执行其他的东西,比如我们在浏览器输入一个地址敲回车就可以发送请求并且接收服务器得响应。所以说浏览器的第一功能是请求一个http地址,也就是可以封装一个请求报文出来,将一个url的地址封装成一个请求报文,这个报文到服务端,然后给我们一个响应报文,然后在将响应解析出来,这也是浏览器的最大的作用。当然服务器响应的内容有可能不一样,比如说服务器返回一个html文件,css文件,img文件,用来渲染,我们称之为渲染引擎,除此之外,还可以执行js,由js引擎来完成,因此可以说javascript的运行环境是浏览器中的js引擎,而不是浏览器。浏览器是一个大的概念。
3) 浏览器中的javascript可以做什么?
之前由提到过,javascrip就是用来做交互的,但是笼统的说交互有点不明确,具体一点可以分为:
- 操作dom(也就是对dom的增删改,注册事件之类的事情)
- 发送AJAX请求/跨域
- BOM交互如给我们提供页面跳转,历史记录,控制台打印日志
- ecmascript(js的核心语言,如用来定义变量,函数等)
4) 浏览器端的javasscript不可以做什么?
通过之前的了解,貌似javascrip对我们日常的交互都可以完成,貌似什么都可以做,但是他也有不能做的事。如:
- 涉及到端对端的应用程序,我们需要操作文件,浏览器中的javascript是不能进行文件操作的,虽然h5里面提供了关于文件相关的API,但是这些API大多数只限于只读的层面 ,不能像传统的语言如java,通过传一个路径,然后将对应的文件读出来,说白了就是不能进行文件和文件间的CURD;
- 浏览器端的javascript也没有办法去操作操作系统,如获取操作系统的版本之类的;
那么为什么不能进行这两类操作?其实是出于安全考虑,因为,js这门语言运行的环境比较特殊,说他特殊,特殊在什么地方?虽然我们编写好的js代码最终会放在服务器上,但是他毕竟不是在服务器上执行的,而是通过服务器发送到浏览器端执行的,在浏览器端执行文件的操作显然是不安全的,因此说这些功能在客户端不是不能做,而是由于特殊的运行环境没法做。
5) javascrip只能运行在浏览器端吗?
了解了客户端的js所能做的事,我们必须还要明确一个概念,那就是javascrip只能运行在浏览器端吗?
前端开发人员都知道,javascrip是有ecmascrip语言,BOM,DOM组成的,在语言层面,她只是给我们提供一些操作语法,如定义变量,函数,类型,流程控制等的操作。而BOM,DOM是浏览器提供的,并非es提供的。因此我们常提及的js其实就是es,js的大部分功能(DOm,BOM(浏览器开放出来的API)等的操作)都是由 浏览器的执行引擎决定的 ,这也衍生出一个观点,任何一门编程语言 ,他的能力不是由语言本身决定的,而是由他的执行环境决定的。比如说java,他即是一门语言也是一个平台,对于javascript来说语言就是es,平台是浏览器。那么js只能运行在浏览器中吗?非也!对于大多数语言,都是运行 在一个平台上的,比如java只运行在虚拟机上,但是也有运行在多个平台的语言, java在一定层面上来讲是没有必要运行在多个平台上的,因为虚拟机是跨平台(也就是跨操作系统如window,linux等)的。js同样是可以运行在多个平台的,浏览器之所以能够运行js,是因为他有js的执行引擎。js同样,只要有支持他的平台就可以执行。因此说要想语言有很强大的功能,只需要提供强大的平台,node就是这样一个平台,能够执行js,那么node到底是什么东西?
6)什么是node?
node平台 = JS引擎 + 巨量新的API;
根据官方文档可以知道,node就是一个给予谷歌v8引擎的一个javascript的运行时的平台,可以理解为运行js的一个虚拟机。他使用的是一个 事件驱动,非阻塞I/O模型 ,他是将js的运行环境搬到了服务器端,和客户端没有一点关系。是一个纯服务端的东西,node只是为js提供了一个平台。node里面其实还分了两块,一是封装了v8引擎,目的是为了执行es(如定义变量,定义函数等),另外一个提供了大量的工具库,是帮助node实现各种功能的,提供了一些以前js的环境办不到的事情,比如文件操作,网络操作,操作系统的操作。
既然node是一个平台(所谓的平台就是用来运行特定语言的),也就意味着node是用来运行语言的,那么java也是语言,node能运行java吗?据nodejs创始人Ryan Dahl回忆,他最初是选择了Ruby这门语言,但是Ruby这门语言的虚拟机效率不怎么样最终放弃了,按照这种思路,貌似node将java的虚拟机集成进来应该可以运行java,但node作者最终选择了javascript。这样js就实现了在服务端运行的可能,js运行在node平台上(分为v8部分,用来执行es,和大量的工具库组件(API)称之为libuv,提供了以前js的环境办不到的事,如文件操作,网络操作等等)。
知道了什么是node,应该还要清楚node在web中有什么用途?
(1)node可以接受客户端用户的所有请求,并且能够快速的给出响应,因此node可以用来做网站。
(2)node可以作为一个中间层来来分发调用数据接口,比如有一个网站数据是有java提供的,我们可以让node作为一个中间层,来接受用户的请求,然后通过node来调用java数据接口,获取到数据后直接在node层面做html的封装,然后将渲染好的页面直接给用户。为什么要这样做,直接请求java接口不行吗,这是因为node被称之为高性能的web服务器,在并发和抗压方面都比传统的平台要好很多,因此这样一包装可以极大的减轻服务器的开发。
通过上面的两点,可以总结出,node在web中要么从前端页面到后端服务全包了,一个是只做其中的一点。
一言以蔽之,node就是一个javascript的运行环境(平台),他不是一门语言,也不是javascript的框架。可以用来开发服务端应用程序,web系统。其特点是体积小,快速,高性能。
简单的说 Node.js 就是运行在服务端的 JavaScript。
Node.js 是一个基于Chrome JavaScript 运行时建立的一个平台。
Node.js是一个事件驱动I/O服务端JavaScript环境,基于Google的V8引擎,V8引擎执行Javascript的速度非常快,性能非常好。
2. node环境的安装
- 中文官网: http://nodejs.cn
- 可以在cmd(window+ r打开cmd) node -v 命令来查看当前的 Node 版本;
- 注意:不同版本间可能是有差异的
3. 运行Node.js程序
运行步骤:
1) 创建helloWorld.js文件
cosole.log("hello world");
2) HBulider -> 文件-> 在外部资源管理器打开->地址栏 cmd+回车->node命令 node helloWorld.js 来执行程序(tab键自动补齐文件名)
通过http模块创建服务器:
如果我们使用PHP来编写后端的代码时,需要Apache 或者 Nginx 的HTTP 服务器,来处理客户端的请求相应。不过对 Node.js 来说,概念完全不一样了。使用 Node.js 时,我们不仅仅在实现一个应用,同时还实现了整个 HTTP 服务器。
js文件:
1) 引入http模块
2)http.createServer()方法创建服务器,函数通过 request, response 参数来接收和响应数据
3) listen() 方法绑定端口
//1. 引入http模块
const http = require("http");
//2. 创建一个服务器,回调函数表示接收到请求之后做的事情
let server = http.createServer(function(req,res){
res.writeHead(200,{"Content-type":"text/html;charset=utf-8"});
res.write("haha");
res.write("xixi");
res.end(结束了);
});
// 监听
server.listen(8866);
node 命令编译-> 浏览器运行:127.0.0.1:8866或者浏览器ip地址:端口号
所以:我们本地写一个js文件,是不能直接拖到浏览器运行的。但是有了node,我们任何一个js文件,都可以通过node来运行。也就是说,node就是一个js的执行环境。
4. Node.js 中的模块化
JavaScript是一个强大面向对象语言,它有很多快速高效的解释器。然而, JavaScript标准定义的API是为了构建基于浏览器的应用程序。并没有制定一个用于更广泛的应用程序的标准库。
CommonJS规范的提出,主要是为了弥补当前JavaScript没有标准的缺陷。它的终极目标就是:提供一个类似Python,Ruby和Java语言的标准库,而不只是停留在小脚本程序的阶段。
用CommonJS API编写出的应用,不仅可以利用 JavaScript开发客户端应用,而且还可以编写以下应用。
- 服务器端JavaScript应用程序。(nodejs)
- 命令行工具。
- 桌面图形界面应用程序。
CommonJS就是模块化的标准,nodejs就是CommonJS(模块化)的实现。
Node应用由模块组成,采用CommonJS模块规范。
在Node中,模块分为三类:
- 一类是Node提供的模块,称为核心模块,如http模块,fs模块;
- 另一类是用户编写的模块,称为文件模块;
- 第三类是第三方模块;
CommonJS(Nodejs)中自定义模块的规定:
- 我们可以把公共的功能抽离成为一个单独的 js 文件作为一个模块,默认情况下面这个模块里面的方法或者属性,外面是没法访问的。如果要让外部可以访问模块里面的方法或者属性,就必须在模块里面通过 exports 或者module.exports暴露属性或者方法。
- 在需要使用这些模块的文件中,通过require的方式引入这个模块。这个时候就可以使用模块里面暴露的属性和方法。
案例:
7-CommonJS.js:使用require,导入模块
注意:同级./不能省略;后缀.js可以省略;
// 导入模块: require(模块名称),返回该模块对象
const a = require("./7-config.js");
console.log(a.str);
a.fun();
7-config.js:
使用exports或者module.exports暴露属性或方法
//导出规则
let str = "xixi";
exports.str = str;
function fun(){
console.log("haha");
}
//module.exports 和exports 等同
module.exports.fun = fun;
注意:以上两个文件只需要编译7-CommonJS.js文件即可运行;
ES6:
1) html文件中用script的src属性引入导出文件, 并且type值为module
<script referrerpolicy="no-referrer" src='8-ES6CommonJS.js' type='module'></script>
2) export 暴露属性和方法, 注意没有s
3) import {属性或函数...} from 路径;
import {str,add} from "./8-ES6config.js";
8-ES6.html文件:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
</head>
<body>
</body>
</html>
<script src='8-ES6CommonJS.js' type='module'></script>
8-ES6config.js文件
export let str = "666";
export function add(a, b) {
return a + b;
}
8-ES6CommonJS.js文件
//import {属性或函数...} from 路径;
import {str,add} from "./8-ES6config.js";
console.log(str);
console.log(add(1,2));
5. 包与NPM
包
Nodejs中除了它自己提供的核心模块外,我们可以自定义模块,也可以使用第三方的模块。Nodejs中第三方模块由包组成,可以通过包来对一组具有相互依赖关系的模块进行统一管理。
在NodeJs中通过NPM命令来下载第三方的模块(包)
- https://www.npmjs.com/package...
- 命令: npm i silly-datetime i是install的缩写 -》安装完后会在文件夹自动下载个包
const sd = require("silly-datetime"); console.log(sd.format(new Date(), 'YYYY-MM-DD HH:mmjs));
- node 9-npm.js 命令运行:
npm是随着node一起安装的, 下载了node肯定也安装了npm。
2) NPM介绍
- npm是世界上最大的开放源代码的生态系统。我们可以通过npm下载各种各样的包,这些源代码(包)我们可以在https://www.npmjs.com找到;
npm是随同NodeJS一起安装的包管理工具,能解决NodeJS代码部署上的很多问题,常见的使用场景有以下几种:(npm是随着node一起安装的, 下载了node肯定也安装了npm。)
- 允许用户从NPM服务器下载别人编写的第三方包到本地使用。(silly-datetime);
- 允许用户从NPM服务器下载并安装别人编写的命令行程序(工具)到本地使用。(supervisor);
- 允许用户将自己编写的包或命令行程序上传到NPM服务器供别人使用。
3)npm命令详解
- npm -v //查看npm版本
使用 npm 命令安装模块
- npm install ModuleName
- 如安装jq模块 npm install jquery
- npm uninstall moudleName //卸载模块
- npm list //查看当前目录下已安装的node包
npm info 模块 //查看模块的版本
- npm info jquery 查看jquery的版本
4) node自动重启工具 nodemon
为什么要使用nodemon?
- 在编写调试Node.js项目,修改代码后,需要频繁的手动close掉,然后再重新启动,非常繁琐。现在,我们可以使用nodemon这个工具,它的作用是监听代码文件的变动,当代码改变之后,自动重启。
如何使用 nodemon?
- npm install -g nodemon 安装后直接使用 nodemon js文件名
6. fs模块(文件与目录操作)
首先引入fs文件流:
//fs: file stream 文件流
const fs = require("fs");
fs模块的回调函数必须写,否则报错;
1) 读文件 fs.readFile()
语法:
fs.readFile(文件路径,function(err,data){});
//如果文件路径正确,则不产生err;
fs.readFile("2fs.txt", function(err, data) {
if (!err) {
// console.log(data); //<Buffer e4 bb 8a e5 a4...>
//toString()将文件内容的编码格式转化为字符流
console.log(data.toString());
}
});
node命令运行代码,结果在cmd窗口
2) 写文件 fs.writeFile()
写文件的本质为替换文件,如果源文件存在,则直接替换;若不存在,则创建新文件;
语法:
fs.writeFile(路径,书写内容,[书写方式],回调函数);
书写方式:{flag: "a"/"w"}
a: append追加
w: write(默认)
fs.writeFile("2fs.txt","天气下雨了",{flag:"a"},function(){});
//node命令运行,然后在2fs.txt中点击一下鼠标就能看到结果
3) 创建文件夹 fs.mkdir()
fs.mkdir(文件夹名称,回调函数);
fs.mkdir("mycss",function(){});//在同一路径下,创建了文件夹
4) 追加文件 fs.appendFile()
fs.appendFile(路径,内容,回调函数);
fs.appendFile("2fs.txt","我有一只小毛驴",function(){});
5) 删除目录 fs.rmdir()
fs.rmdir(目录名,回调函数);
fs.rmdir("mycss",function(){});
6) 删除文件 fs.unlink()
fs.unlink(文件名,回调函数);
fs.unlink("1-fs.txt",function(){
console.log("文件删除成功");
});
7) 判断路径指向的是文件还是文件夹 fs.stat()
fs.stat("css",function(err,stat){
if(!err){
console.log(stat.isDirectory());//true
console.log(stat.isFile());//false
}
})
7. 路由
- 官方解释: 路由(Routing)是由一个 URI(或者叫路径)和一个特定的 HTTP 方法(GET、POST 等)组成的,涉及到应用如何响应客户端对某个网站节点的访问。
- 非官方解释: 路由指的就是针对不同请求的URL,处理不同的业务逻辑。
案例,创建服务器,运行或自动监视该js文件,然后如果在浏览器输入127.0.0.1:8850/login,则返回login.html的页面。
注意: 端口号可选范围是0-65535,但是8000以下已经被固定软件占用,如http端口是80,8848是apach服务器的,3366是mysql服务器的。我们一般使用8000以上的端口号。
const http = require("http");
const fs = require("fs");
http.createServer(function(req,res){
res.writeHead(200,{"Content-Type":"text/html;charset=utf-8"});
// req.url代表是斜杠后的名称
console.log(req.url);// /login
// 浏览器地址栏输入127.0.0.1:8850/login,则会满足下面条件
if(req.url=="/login"){
fs.readFile("login.html",function(err,data){
if(!err){
res.end(data);//显示login.html页面
}
});
}else if(req.url=="/admin"){
res.end("管理员");
}else if(req.url=="/res"){
res.end("注册");
}
}).listen(8850);//注意端口号不能被别的占用
htm文件:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
</head>
<body>
<ul>
<li>我是真正的登录页面</li>
</ul>
</body>
</html>
/favicon.ico 自带的,不用管
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。