(1) 浏览器中可执行javaScript的组成部分
javaScript被解析引擎解析过后可以被浏览器执行,不同的浏览器解析引擎不同
(2)初识node
node.js:.基于ChromeV8j引擎的一个avaScript的运行环境
Chrome浏览器的运行环境:
总结:v8引擎负责解析和执行javaScript代码,内置API则是运行环境提供的特殊接口,脱离环境无法调用
node.js运行环境:
(3)Node.js功能:
node.js仅仅提供了基础的功能,然而基于这些基本功能,很多强大的工具和框架应运而生。如:
- express框架:(https://www.expressjs.com.cn/)快速构建web应用
- electron框架:(http://www.electronjs.org/)快速构建跨平台的桌面应用
- restify框架:(http://restify.com/)快速构建API接口项目
- 读写和操作数据库,创建命令行工具辅助前端开发
- etc
(4)node.js学习路径:javaScript语法+node.js内置API(fs、path、http)+第三方API模块(express、mysql)
(5)常用终端命令:
- cd xxx: 切换目录
- node filename.js 执行js文件
- top键:可以快速定位到上一次执行的命令
- tab键:快速补全文件路径
- esc键:快速清空当前已输入的命令
- cls:清空当前终端
(6)fs文件系统
- 文件模块导入:
const fs = require('fs')
-
读取文件
const fs = require('fs') //1.导入fs模块 fs.readFile('https://docs.qq.com/doc/DTE1Xc0VEcGRBaE9p?&u=56380174994c45b9b6ad2e676b7f0de5','utf8',function(error,dataStr){ if(error!==null){ console.log('error',error) } console.log('dataStr',dataStr) })
fs.readFile(path[,options],callback):path:文件路径;options:以什么编码方式来读取文件;callback: 文件读取结果
-
写入文件
const fs = require('fs') fs.writeFile('','写入文件的内容','utf8',function(error){ if(error!==null){ console.log('error',error) } })
fs.writeFile(path,data[,option],callback):path:文件路径;data:写入内容;options:以什么编码方式来读取文件;callback: 文件写入结果
(7)path路径模块
path模块是node.JS官方提供的,用来处理路径的模块,它提供了一系列的方法和属性,用来满足用户对路径的处理需求。
路径模块导入
const path = require('path')
- __dirname: 获取文件所在绝对目录
- path.join(...pathStr): 将路径片段拼接成一个完整路径
- path.basename(path[,ext]):从一个文件路径中获取文件名称
- path<string>,表示一个路径字符串
- ext<string>可选参数,表示文件扩展名
- 返回<string>路径最后一部分
const path = require('path') path.basename('../test/test.html','.html') //test
- path.extname(path):从文件路径中获取文件扩展名
const path = require('path') path.basename('../test/test.html') //.html
(8)http服务器模块
客户端:消费资源的电脑叫做客户端;服务器:对外提供网络资源的电脑
http模块式node.js官方提供的web服务器模块。通过http模块http.creatServer() 就可以将一台普通的电脑变成web服务器,从而对外提供web资源服务。
创建web服务器的基本步骤
- 导入http模块
const http = require('http')
- 创建web服务器实例
const server = http.creatServer()
- 为web服务器实例绑定request事件,并监听客户端请求
server.on('request',function(request,response){ console.log('request.path',request.path) console.log('request.method',request.method) response.setHeader('Content-Type','text/html;charset=utf-8') response.end('这是返回值') })
- 启动服务器
server.listen(8080,function(){ console.log('Someone is requesting host of 127.0.0.1:8080') })
(9) 模块化
概念:模块化是指解决一个复杂问题师,自顶向下逐层把问题划分成若干个模块的过程。对于紫铜来说,模块是可组合,分解和更换的单元。编程领域的模块化指的是遵守固定的规则,把一个大文件拆成独立且相互依赖的多小模块。
模块化的好处:
- 提高了代码的复用性
- 提高了代码的可维护性
- 可以实现按需加载
模块化规范:模块化规范就是对代码进行拆分与组合的时候 ,需要遵守的那些规则。例如:使用什么样的语法来引用模块,怎样暴露模块成员...
使用require()方法加载内置模块、自定义模块、第三方模块,会执行其中代码
- require('moduleName') 加载内置模块
- require('moduleRelPath') 加载自定义模块
- require('moduleName') 加载第三方模块
模块作用域的好处:防止全局变量污染
向外共享模块作用域
module里面存了和当前模块有关的信息,例如:id,fileName,path,exports(默认为空对象),loaded:Boolean,parent等;在自定义模块中,可以使用module.exports对象讲模块内的成员共享出去,供外界使用,外界用require()方法导入自定义模块时,得到的永远是module.exports指的对象,例:module.exports.sayHello=function(){}
exports是module.exports代码简化向外共享对象的结果,exports===module.exports,但是最终结果总是以module.exports为主
node.js遵循Common.js规范:
- 每个模块内部,module变量代表当前模块
- module变量是一个对象,它的exports属性是对外的接口
- 加载某个模块,其实加载的是模块的exports属性,require()方法用来加载模块
(10)npm与包
- 包的概念:模块的基本单位是单个JS文件,但复杂些的模块往往由多个子模块组成。为了便于管理和使用,我们可以把由多个子模块组成的大模块称做
包
,并把所有子模块放在同一个目录里
初次安装包后项目会多出来node_modules和package-lock.json文件夹,node_modules下是项目依赖的包,package-lock.json中存放的是包的信息(版本,id...),可以通过
npm install(i) packageName@version安装指定版本的包
- 包的语义化版本规范:
包的版本号是以”点分十进制“形式进行定义的,总共有三位数字,例如2.24.0,其中每一 位数字所代表的含义如下:
第一位数字:大版本
第二位数字:功能版本
第三位数字: Bug修复版本
- 包管理配置文件:npm规定,在项目根目录中,必须提供一个叫做package.json的包管理配置文件,用来记录与项目有关的一些配置信息,例如:项目的名称、版本号、描述,开发包、部署包等
- npm init -y 在命令行所处的目录中,快速新建package.json文件,注意:package.json中的name属性值为包名,main属性值为包入口文件路径,如果未指定,则默认入口文件为index.js
- 包发布流程:注册=>下包服务器切换到npm=>登录=>切换到包根目录=>npm publish 发布
- 删除包流程: npm unpublish 包名 --force命令,即可以从npm删除包(3天内)
(11)模块加载机制:
- 模块导入加载之后会缓存,不会重复加载
- 使用require()加载自定义模块时,必须指定以./或者../开头的路径标识符,没有指定则当作内置模块或者第三方模块
- 在用require()导入自定义模块时,如果省略了文件扩展名,则node会按照以下文件加载
- 按照确切的文件名进行加载
- 补全js扩展名进行加载
- 补全json扩展名进行加载
- 补全node扩展名进行加载
- 加载失败,终端报错
- 第三方模块加载机制:以所在父目录查找node_modules,查不到向上继续查找,直到根目录
(12)express:基于node.js的web开发平台
学习目标:
- 能够使用express.static快速托管静态资源
- 能够使用express精简路由精简项目结构
- 能够使用常见的express中间件
- 能够使用express创建API接口
- 能够在express中启用cors跨域资源共享
对于前端程序员来说,最常见的两种服务器分别是:
- Web网站服务器,专门对外提供Web网页资源的服务器
- API接口服务器,专门对外提供API接口的服务器
使用express,我们可以方便快速的创建web网站服务器或者API接口服务器
express创建服务器实例流程:
- const express = require('express') //导入express模块
- const app = express() //创建服务器实例
- app.on('host',()=>{console.log('服务器启动了')}) //启动服务器
监听GET/POST请求
app.get('requestUrl',function(req,res){}) // 请求路径,处理函数,req:请求对象(包含了与请求相关的属性与方法),res:响应对象(包含了与相应对象相关的属性与方法)
app.get('/path:id',(req,res)=>{
req.query.paramName //获取URL中携带的查询参数
req.params.paramName //获取请求路径中的动态参数
res.send('请求成功') //发送数据'请求成功'到客户端
})
(13)托管静态资源:express.static托管静态资源
express提供了一个非常好的方法,express.static(),通过它,我们可以非常方便的创建一个静态资源服务器,例如:通过以下代码就可以将public目录下的图片、css文件、js文件对外开放访问了
app.use(express.static('public'))//public目录下的所有文件都会被放置到静态服务器上
注意:express再指定的静态目录文件夹中查找文件,并对外提供资源的访问的路径,因此存放静态文件的目录名不会出现再url中,例:http://lovalhost:8080/imgs/1.png http:/localhost:8080/css/index.css,http://localhost:3030.8080/index.js
nodeman:监听项目代码,当代码发生变化时,自动重启项目
(14)前后端认证机制
- web开发模式:
- SSR(服务端渲染):服务器发送的HTML页面是在服务器通过字符串拼接,动态生成的,因此客户端不需要使用Ajax这样的技术额外请求页面的数据,优点:
- 前端耗时少,因为服务器端负责动态生成HTML内容,浏览器直接渲染页面即可,尤其移动端,更省电
- 有利于SEO,因为服务端响应的是完整的HTML内容,所以爬虫更容易获得信息,有利于SEO
缺点: - 占用服务器资源,即服务器端完成HTML内容的拼接,如果同时访问数量较多,则会造成服务器压力
- 不利于前后端分离,开发效率低,使用服务端渲染,则无法进行分工合作,尤其前端复杂的项目,不利于项目高效开发
- 前后端分离:后端提供API,前端调用。优点:
- 开发体验好,能专注于UI界面的开发,后端专注于API的开发,且前端有更多选择
- 用户体验好,AJAX技术的广泛应用轻松实现页面局部刷新,
- 减轻了服务端的渲染压力,因为每个页面最终在浏览器生成
缺点: - 不利于SEO,因为完整的HTML页面需要在客户端动态拼接完成,所以爬虫无法爬取页面有效信息,解决方案:利用vue,react,angular等框架的SSR(sever side render)技术能够很好解决seo问题
- 企业级网站,主要用来做展示而交互少,并且需要良好的seo,如官网,选择SSR
- 而后台管理项目,交互性强而且不需要考虑seo,可以采用前后端分离模式
- 选择开发模式并不固定,为了兼顾首页渲染速度和前后端分离开发的效率,一些网站采用了首屏SSR+其他页面前后端分离的模式
- SSR(服务端渲染):服务器发送的HTML页面是在服务器通过字符串拼接,动态生成的,因此客户端不需要使用Ajax这样的技术额外请求页面的数据,优点:
Session认证机制
什么是cookie:cookie是存储在用户浏览器中的一段不超过4KB的字段,它有一个名称(name)、一个值和其他用来控制有效期、安全性、使用范围的可选属性组成,一般不用来存储重要的隐私信息
JWT认证机制
1.了解session认证的局限性
session认证机制需要配合cookie才能实现,由于cookie默认不支持跨域访问,所以当涉及到前端跨域请求后端接口时,需要做很多额外的配置,才能实现跨域session认证
注意:当前端请求后端接口不存在跨域问题的时候,推荐使用session身份认证机制
当前端需要跨域请求后端接口的时候,不推荐使用session身份认证机制,推荐使用JWT认证机制
2.JWT:全程JSON Web Token,是目前最流行的跨域认证解决方案
JWT工作原理:
用户信息通过Token字符串的形式,保存在客户端浏览器,服务器通过还原token字符串的形式来认证用户信息
3JWT分别由以下三部分组成,分别是header(头部),payload(有效载荷),signature(签名)组成
三者之间通过英文的"."链接,格式如下:Header.Payload.Signature,payloa是用户信息经过加密之后生成的字符串,header和signature是为了保证payload的安全性
客户端收到服务端的JWT后,通常会储存在localStorage或者sessionStorage中,推荐把JWT放在http的authorization字段中,格式如下:
authorization: Bearer<token>
4.在express中使用JWT
需要用到两个相关的包,jsonwebtoken、express-jwt
jsonwebtoken用于生成jwt字符串,express-jwt用于将jwt字符串还原成json对象
通过jsonwebtoken包提供的sign方法,将用户信息加密成JWT字符串,响应给客户端
jsonwentoken.sign(userInfo,secrectKey,settingObj) //userInfo:用户信息,secrectkey:密钥,settingObj:配置对象
通过express.JWT这个中间件,将客户端发送过来的token解析成json对象
express.JWT({secrect:secrectKey}).unless(/.../)
可以通过unless指定哪些接口不需要进行访问权限