- Node开发概述
- 为什么要学习服务器端开发基础?
- 能够和后端程序员更加紧密的配合
- 网站业务逻辑前置【原本需要后端人员去做的事情,交由前端人员去处理】,学习前端技术需要后端技术支撑(Ajax)
- 扩宽知识视野,能够站在更高的角度审视整个项目
- 服务器开发要做的事情:
- 实现网站的业务逻辑
- 比如网站中常见的登录功能:
- 为什么用户在输入完用户名和密码之后,就可以实现登录了呢:
- 比如网站中常见的登录功能:
- 数据的增删改查
- 实现网站的业务逻辑
- 为什么选择Node
- 使用JavaScript语法开发后端应用
- 一些公司要求前端工程师掌握Node开发
- 生态系统活跃,有大量开源库可以使用
- 前端开发工具大多基于Node开发
- Node是什么
- Node是一个基于ChromeV8引擎的JavaScript代码运行环境。
- 运行环境:
- 浏览器(软件)能够运行JavaScript代码,浏览器就是JavaScript代码的运行环境
- Node(软件):能够运行JavaScript代码,Node就是JavaScript代码的运行环境。
- 运行环境:
- Node是一个基于ChromeV8引擎的JavaScript代码运行环境。
- 为什么要学习服务器端开发基础?
- Node运行环境搭建:
- Node.js运行环境安装
- 官网:https://nodejs.org/en/
- LTS=Long Term Support长期支持版 稳定版【我们下载这个】
- Current拥有最新特性 实验版
- 官网:https://nodejs.org/en/
- Node环境安装失败解决办法:
- 错误代号2502、2503:
- 失败原因:系统账户权限不足。
- 解决办法:
- 以管理员身份运行powershell命令行工具
- 输入运行安装包命令msiexec /package node安装包位置
- 执行命令node -v报错
- 失败原因:Node安装目录写入环境变量失败
- 解决办法:将Node安装目录添加到环境变量中【系统环境变量path中】
- 错误代号2502、2503:
- Node.js运行环境安装
- PATH环境变量
- 存储系统中的目录,在命令行中执行命令的时候,系统会自动去这些目录中查找命令的位置。
- Node.js快速入门
- Node.js的组成
- JavaScript由三部分组成,ECMAScript,DOM,BOM.
- Node.js是由ECMAScript及Node环境提供的一些附加API组成的,包括文件,网络,路径等等一些更加强大的API。
- Node.js基础语法:
- 所有ECMAScript语法在Node环境中都可以使用。
- 打开文件所在位置
- 按住shift键+鼠标右键
- 在弹出的菜单栏中选中“在此处打开Powershell窗口”
- node 文件名【文件名需加后缀,输入文件名前几个字符,按下tab键可以自动补全该文件】即可执行该文件
- 所有ECMAScript语法在Node环境中都可以使用。
- Node.js的组成
- Node.js模块化开发。
- JavaScript在使用时存在两大问题,文件依赖和命名冲突。
- 文件依赖:【文件之间依赖关系不明确】
- 由JavaScript的引入先后顺序决定的
- 命名冲突:【不同文件里面出现相同变量,后面的会覆盖前面的】
- 文件依赖:【文件之间依赖关系不明确】
- 生活中的模块化开发:
- 电脑的组装方式->采用的模块化方式,完整的电脑是由显示器、键盘、鼠标、硬盘、CPU、内存以及一些硬件组成的。这些不同的硬件都是由不同的厂商生产的,再将这些硬件通过某种方式组装起来,这种组装的方式就属于模块化方式。
- 这种组装方式的好处:某个部件坏了,只需要换坏掉的部间【某一个模块的损坏并不会影响其他模块的正常运行,只需要把坏掉的模块重新换掉就可以了。】
- 软件中的模块化开发:
- 一个功能就是一个模块,多个模块可以组成完整应用,抽离一个模块不会影响其他功能的运行。
- Node.js中模块化开发规范
- Node.js规定一个JavaScript文件就是一个模块,模块内部定义的变量和函数默认情况下在外部无法得到。
- 模块内部可以使用exports对象进行成员导出,使用require方法导入其他模块。
- 当前模块成员导出:
- exports.自定义导出对象的属性名=当前文件中的成员变量
- 当前模块成员导出:
- JavaScript在使用时存在两大问题,文件依赖和命名冲突。
当前文件的成员变量可以是方法,也可以是变量,还可以是函数。
- 其他模块导入当前模块的成员变量:
- var 自定义保存成员对象名=require(‘当前模块相对路径’)
- 其他模块导入当前模块的成员变量:
导入模块时,当前模块相对路径 其后缀可以省略
- 使用时用自定义保存成员变量名
可以使用导出模块exports的变量和方法以及函数
- 模块成员导出的另一种方式
- module.exports.version = version;
- module.exports.sayHi = sayHi;
- exports是module.exports的别名(地址引用关系),导出对象最终以module.exports为准。
- 当module.exports【模块成员导出】赋值为对象时,只能用module.exports.属性名在对象里面添加属性。
- exports=对象是错误的写法。
- 系统模块
- 什么是系统模块?
- Node运行环境提供的API。因为这些API都是以模块化的方式进行开发的,所以我们又称Node运行环境提供的API为系统模块
- 文件模块
- 读取文件
- 写入文件
- 创建文件夹
- 文件模块
- Node运行环境提供的API。因为这些API都是以模块化的方式进行开发的,所以我们又称Node运行环境提供的API为系统模块
- 什么是系统模块?
- 系统模块fs文件操作
- f:file文件,s:system系统,文件操作系统。
- 语法:const fs = require(‘fs’)
- 读取文件内容:
- fs.readFile(‘文件路径/文件名称’[,’文件编码]’,(err,doc) =>{
- 读取文件内容:
})
- 如果文件读取发生错误,参数err的值为错误对象,否则err的值为null
如果文件读取出错err是一个对象,包含错误信息
如果文件读取正确,err是null
doc是文件读取的结果
- doc参数为文件内容
- 写入文件内容
- fs.writeFile(‘文件路径/文件名称’,’数据’,(err,doc) =>{
})
- 当文件不存在,会自动创建并写入数据
- 当文件纯在时,会先将该文件前面的代码执行完毕,再替换文件,重写
- 系统模块path路径操作
- 为什么要进行路径拼接?
- 不同操作系统的路径分隔符不统一
- 为什么要进行路径拼接?
路径分隔符:文件夹与文件夹之间的分隔符
Windows上是/或\
Linux上是/
Linux通常用作网站的服务器
- 路径拼接语法【是在js文件内导入写代码】:
- 导入path模块
- 路径拼接语法【是在js文件内导入写代码】:
const path = require('path');
- 路径拼接
let finalPath = path.join('路径', '路径', ...)
- 相对路径VS绝对路径
- 大多数情况下使用绝对路径,因为相对路径有时候相对的是命令行工具的当前工作目录
- 在读取文件或者设置文件路径时都会选择绝对路径
- 相对路径不安全
- 使用__dirname【两个下划线+dirname】获取当前文件所在的绝对路径,再利用path.join()方法进行路径拼接
- 相对路径VS绝对路径
- 第三方模块:
- 什么是第三方模块
- 别人写好的,具有特定功能的,我们能直接使用的模块即第三方模块,由于第三方模块通常都是由多个文件组成并且被放置在一个文件夹中,所以又名包。
- 第三方模块有两种纯在形式:
- 以js文件的形式存在,提供实现项目具体功能的API接口。
- 以命令行工具形式存在,辅助项目开发。
- 获取第三方模块
- npmjs.com:第三方模块的存储和分发仓库
- npm(node package manager):node的第三方模块管理工具
- 下载:npm install模块名称
- 卸载:npm uninstall package模块名称
- 全局安装与本地安装:
- 命令行工具:全局安装
- 库文件:本地安装
- 第三方模块nodemon
- nodemon是一个命令行工具,用以辅助项目开发。
- 在node.js中,每次修改文件都要在命令行工具中重新执行该文件,非常繁琐。
- nodemon当文件发生保存操作时,就会重新执行该文件,保存后在页面可以直接看到效果。
- 使用步骤:
- 使用npm install nodemon -g 下载它
- 全局安装
- 在命令行工具中用nodemon命令替代node命令执行文件
- 使用npm install nodemon -g 下载它
- 按住ctrl + c退出nodemon
- 第三方模块nrm
- nrm(npm registry manager):npm下载地址切换工具
- npm默认的下载地址在国外,国内下载速度慢【甚至经常出现下载失败的情况】
- 国外:npmjs.com
- 国内:npm.taobao.org
- npm默认的下载地址在国外,国内下载速度慢【甚至经常出现下载失败的情况】
- 使用步骤:
- 使用npm install nrm -g下载它
- 查询可用下载地址列表 nrm ls
- 前面有*号的为默认下载地址。
- 切换npm下载地址nrm use 下载地址名称
- 目的是提高我们的下载速度。
- nrm(npm registry manager):npm下载地址切换工具
- 第三方模块Gulp:
- 基于node平台开发的前端构建工具。
- 将机械化操作编写成任务,想要执行机械化操作时执行一个命令行命令任务就能自动执行了
- 用及其代替手工,提高开发效率。
- Gulp能做什么
- 项目上线,HTML,CSS,JS文件压缩合并
- 语法转换(es6,less…)
- 公共文件抽离
- 修改文件浏览器自动刷新。
- Gulp使用步骤
- 使用npm install gulp下载库文件
- 在项目根目录下【src】建立gulpfile.js文件
- 重构项目的文件夹结构src目录放置源代码 文件dist目录放置构建后文件。
- 在gulpfile.js文件中编写任务
- 在命令行工具中执行gulp任务。
- Gulp中提供的方法
- gulp.src(‘需要获取的文件路径’):获取任务要处理的文件
- gulp.dest(‘输出文件位置’):输出文件
- gulp.task(‘任务名字’,回调函数):建立gulp任务
- gulp.watch:监控文件的变化
- gulp任务使用【以下内容写在gulpfile.js文件中】:
- //引用gulp模块
- 基于node平台开发的前端构建工具。
- 什么是第三方模块
const gulp = require(‘gulp’);
- //建立任务
gulp.task(‘任务名字’,() => {
//获取要处理的文件
gulp.src(‘./src/css/base.css’)
//将处理后的文件输出到dist目录
.pipe(gulp.dest(‘./dist/css’));
})
- //执行任务
- 通过命令行工具执行
- //执行任务
下载
npm install gulp-cli -g
- 在命令行中输入:gulp 任务名字
clear 命令可以清屏
- gulp插件
- gulp-htmlmin:html文件压缩
- .pipe(htmlmin({ collapsewhitespace: true}))
- gulp-csso:压缩css
- gulp-babel:javaScript语法转化【es6转换为es5】
- gulp-less:less语法转化
- gulp-uglify:压缩混淆JavaScript
- gulp-file-include:公共文件包含
- browsersync浏览器实时同步
- gulp-htmlmin:html文件压缩
- gulp插件使用:
- 下载插件
- 引入插件
- 调用
- gulp插件
- Html任务:
- Html文件中代码的压缩操作
- 下载插件:npm install gulp-htmlmin
- 引用插件【引入到gulpfile.js文件中】:const htmlmin = require(‘gulp-htmlmin’);
- 建立任务:gulp.task(‘任务名字’,() => {
- Html文件中代码的压缩操作
});
- 在任务中获取html文件:
- gulp.task(‘htmlmin’,() => {
- 在任务中获取html文件:
gulp.src(‘./src/*.html’)
});
- 压缩html文件代码
- gulp.task(‘任务名字’,() => {
- 压缩html文件代码
gulp.src(‘./src/*.html’);
.pipe(htmlmin({ collapsewhitespace: true }))
});
- 抽取html文件中的公共代码。
- 下载插件:npm install gulp-file-include
- 引用插件【引入到gulpfile.js文件中】:const fileinclude = require(‘gulp-file-include’);
- 建立任务,抽取公共代码【在压缩代码之前】:
- gulp.task(‘htmlmin’,(done) => {
- 抽取html文件中的公共代码。
//获取src文件夹下面所有的html文件
gulp.src(‘./src/*.html’);
//抽取公共代码
.pipe(fileinclude())
//压缩html文件代码
.pipe(htmlmin({ collapseWhitespace: true }))
done()
});
- 在相应需要引入公共部分的地方引入公共代码:
- @@include(‘公共代码路径+文件名’)
- 在相应需要引入公共部分的地方引入公共代码:
- Css任务:
- Less语法转换
- 下载插件:npm install gulp-less
- 引入插件:const less = require(‘gulp-less’);
- 建立任务:gulp.task(‘任务名字’,() => {
- Less语法转换
.pipe(gulp.src(‘./src/css/*.less’,’./src/css/*.css’));
//将less文件转换为css文件
.pipe(less())
//将css文件输出到dist/css下面的文件夹里
.pipe(gulp.dest(‘dist/css’))
});
- Css代码压缩
- 下载插件:npm install gulp-csso
- 引入插件:const csso = require(‘gulp-csso’);
- 建立任务:gulp.task(‘任务名字’,() => {
- Css代码压缩
//选择css文件夹下面的.less文件以及.css文件
gulp.src (‘./src/css/*.less’,’./src/css/*.css’);
//将less文件转换为css文件
.pipe(less())
//将css代码压缩
.pipe(csso())
//将压缩的css代码文件输出到dist/css下面的文件夹里
.pipe(gulp.dest(‘dist/css’))
});
- 在cmd命令行中输入gulp 任务名字即可压缩css文件并输出到css文件夹下
- Js任务:
- Es6代码转换【将es6的代码转换为es5的代码】
- CMD下载插件:npm install gulp-babel @babel/core @babel/preset-env
- 引入插件:const babel = require(‘gulp-babel’);
- 建立任务:gulp.task(‘任务名字’,() => {
- Es6代码转换【将es6的代码转换为es5的代码】
//获取js文件夹下面的所有的js文件
.pipe(gulp.src(‘./src/js/*.js’));
//将js文件语法转换
.pipe(babel({
//判断当前代码的运行环境,将代码转换为当前运行环境所支持的代码
presets: [‘@babel/env’]
}))
//输出
.pipe(gulp.dest(‘dist/js’))
});
- 代码压缩
- 下载插件:npm install gulp-uglify
- 引用插件:const uglify = require(‘gulp-uglify’);
- 建立任务:gulp.task(‘任务名字’,() => {
- 代码压缩
//获取js文件夹下面的所有的文件
.pipe(gulp.src(‘./src/js/*.js’));
//将js文件es6语法转换成es5
.pipe(babel({
//判断当前代码的运行环境,将代码转换为当前运行环境所支持的代码
presets: [‘@babel/env’]
}))
//压缩js代码
.pipe(uglify())
//输出
.pipe(gulp.dest(‘dist/js’))
});
- 复制文件夹:
- gulp.task(‘copy’,() => {
//获取src源代码文件夹下的images文件夹下的所有文件
gulp.src(‘./src/images/*’)
//将获取的images文件夹复制到dist文件夹下面的images文件夹中
.pipe(gulp.dest(‘dist/images’))
})
- 构建任务:
- gulp.task(‘构建任务名’,[‘任务名1’,’任务名2’,任务名3’’,…])
- 在命令行中输入gulp 构建任务名,就会依次执行任务1,任务2,任务3.
- gulp.task(‘构建任务名’,[‘任务名1’,’任务名2’,任务名3’’,…])
- package.json文件
- node_modules文件夹的问题:
- 文件夹以及文件过多过碎,当我们将项目整体拷贝给别人的时候,传输速度会很慢很慢
- 删除node_modules这个文件夹【传递项目的时候不需要传递这个文件夹】
- cmd进入这个文件夹以前的路径,输入npm install.
- 它会找到package.json这个文件,然后找到dependencies这个选项下的依赖,然后去下载它。
- 复杂的模块依赖关系需要被记录,确保模块的版本和当前保持一致,否则会导致当前项目运行报错。
- 文件夹以及文件过多过碎,当我们将项目整体拷贝给别人的时候,传输速度会很慢很慢
- package.json文件的作用
- 项目描述文件,记录了当前项目信息,例如:项目名称,版本,作者,GitHub地址,当前项目依赖了哪些第三方模块等。
- 使用npm init -y命令生成
- package.json文件内容中scripts属性的属性值讲解:
- 别名:‘命令’
- 调用时:npm run 别名
- node_modules文件夹的问题:
- 项目依赖:
- 在项目的开发阶段和线上运营阶段,都需要依赖的第三方包,称为项目依赖
- 这种依赖主要是指项目运行过程中所要依赖的提供API接口的库文件
- 使用npm install 包名命令下载的文件会默认被添加到package.json文件的dependencies字段中
- 在项目的开发阶段和线上运营阶段,都需要依赖的第三方包,称为项目依赖
- 开发依赖:
- 在项目的开发阶段需要依赖,线上运营阶段不需要依赖的第三方包,称为开发依赖。
- 使用npm install 包名 --save -dev命令将包添加到package.json文件的devDependencies字段中
- 项目依赖和开发依赖区分的好处:
- 在不同的环境下下载不同的依赖。
- 下载项目依赖和开发依赖:
- npm install
- 下载项目依赖:
- npm install –production
- 下载项目依赖和开发依赖:
- 在不同的环境下下载不同的依赖。
- package-lock.json文件的作用:
- 它记录了模块与模块之间的依赖关系以及版本以及这个模块的下载地址
- 锁定包的版本,确保再次下载时不会因为包版本而产生问题。
- 加快下载速度,因为该文件中已经记录了项目所依赖第三方包的树状结构和包的下载地址,重新安装时只需下载即可,不需要做额外的工作。
- node.js中模块的加载机制:
- 模块查找规则-当模块拥有路径但没有后缀时:
- require(‘./find.js’);
- require(‘./find’);
- require方法根据模块路径查找模块,如果是完整路径,直接引入模块。
- 如果模块后缀省略,先找同名js文件再找同名js文件夹。
- 如果找到了同名文件夹,找文件夹中的index.js
- 如果文件夹中没有index.js就会去当前文件夹中的package.json文件中查找main选项中的入口文件。
- 如果找指定的入口文件不存在或者没有指定入口文件就会报错,模块没有被找到。
- 模块查找规则-当模块没有路径且没有后缀时:
- Node.js会假设它是系统模块,在系统模块去查找有没有这个模块,有就执行这个系统模块,
- 没有这个系统模块,node.js就会去node_modules文件夹中去查找,它会查找是否有同名js文件,有就执行
- 没有就看node_modules这个文件夹下面有没有同名的这个js文件夹,如果有这个同名文件夹,它会看这个文件夹里面是否有index.js这个文件,有index.js文件就执行这个文件
- 没有index.js查看该文件夹中的package.js中的main选项确定模块入口文件。有就执行
- 否则找不到报错
- 模块查找规则-当模块拥有路径但没有后缀时:
- 服务器基础概念:
- URL:
- 统一资源定位符,又叫URL(Uniform Resource Locator),是专为标识Internet网上资源位置而设的一种编址方式,我们平时所说的网页地址指的即是URL
- URL的组成:
- 传输协议://服务器IP或域名:端口/资源所在位置标识
- http://www.itcast.cn/news/20181018/09152238514.html
- http:超文本传输协议,提供了一种发布和接收HTML页面的方法。
- http://www.itcast.cn/news/20181018/09152238514.html
- 传输协议://服务器IP或域名:端口/资源所在位置标识
- URL:
- 开发过程中客户端和服务端说明:
- 在开发阶段,客户端和服务器端使用同一台电脑,即开发人员电脑
- 客户端:浏览器
- 服务器端:远端的一台电脑
- 开发人员电脑:
- 客户端:浏览器
- 服务器端:Node
- 同一台电脑,怎么通过网络去访问他
- 本机域名:localhost
- 本机IP:127.0.0.1
- 在开发阶段,客户端和服务器端使用同一台电脑,即开发人员电脑
- 创建web服务器:
- 安装node
- 在js文件中写入以下代码
//引用系统模块【用于创建网站服务器的模块】
const http = require('http');
//创建web服务器【app对象就是网站服务器对象】
const app = http.createServer();
//当客户端发送请求的时候
app.on('request', (req, res) => {
//响应[req就是请求对象,res是响应对象]
//req.method是请求方式
if(req.method=”post”){
//跳转内容
res.end()
}else if(req.method=”GET”){
//跳转内容
res.end()
}
res.end('<h1>hi,user</h1>');
})
//监听3000端口
app.listen(3000);
console.log('服务器已经启动,监听3000端口,请访问localhost:3000')
- 访问网站服务:localhost:监听端口号
- HTTP协议:
- HTTP协议的概念:
- 超文本传输协议(英文:HyperText Transfer Protocol,缩写:HTTP)规定了如何从网站服务器传输超文本到本地浏览器,它基于客户端服务器架构工作,是客户端(用户)和服务器端(网站)请求和应答的标准。
- 报文:
- 在HTTP请求和响应的过程中传递的数据块叫做报文,包括要传送的数据和一些附加信息,并且要遵守规定好的格式。
- 报文分类:
- 请求报文【客户端向服务器端请求时所携带的数据块】:
- HTTP协议的概念:
请求报文 | |
请求方式 | Post |
请求地址 | www.ithcast.com |
Hello,请给我一个好消息 |
- 响应报文【服务器端向客户端响应时所携带的数据块[服务器对客户端说话]】:
响应报文 | |
内容类型 | Text/html |
内容长度 | 20 |
Hi,我就是好消息! |
- 请求报文:
- 请求方式(Request Method)
- GET 请求【获取】数据
- 浏览器的图标请求
- 表单跳转行为
- POST 发送【添加】数据
- 表单
- GET 请求【获取】数据
- 案例:
- <form method = “post” action = “http://localhost:3000”>
- 请求方式(Request Method)
<input type = “submit” name = “”>
</form>
- method:指定当前表单提交的方式
- action:指定当前表单提交的地址
- 请求地址(Request URL)
- app.on(‘request’,(req,res) => {
req.headers //获取请求报文
req.url //获取请求地址
req.method //获取请求方法
})
- 获取请求地址req.url:
- 根据地址的不同,响应不同的请求
- 响应报文:
- HTTP状态码:
- 200请求成功
- 404请求的资源没有被找到
- 500服务器端错误
- 400客户端请求有语法错误
- 内容类型:
- text/plain纯文本
- text/html
- text/css
- application/javascript
- image/jpeg
- application/json
- 案例:
- HTTP状态码:
//引用系统模块【用于创建网站服务器的模块】
const http = require('http');
//处理url地址
const url = require('url')
//url.parse()第一个参数为要解析的url地址,第二个参数是将查询参数解析成对象
console.log(url.parse(req.url,true).query);
//创建web服务器【app对象就是网站服务器对象】
const app = http.createServer();
//当客户端发送请求的时候
app.on('request', (req, res) => {
//响应[req就是请求对象,res是响应对象]
res.writehead(200,{
'content-type': "text/html;charset=utf8" //解决中文乱码问题
})
res.end('<h1>hi,user</h1>');
})
//监听3000端口
app.listen(3000);
- console.log('服务器已经启动,监听3000端口,请访问localhost:3000')
- 请求参数:
- 客户端向服务器端发送请求时,有时需要携带一些客户信息,客户信息需要通过请求参数的形式传递到服务器端,比如登录操作。
- GET请求参数:
- 参数被放置在浏览器地址栏中,例如:http://localhost:3000/?name=zhangsan&age=20
- 通过req.url来获取
- POST请求参数:
- 905