node环境的安装
(1)一路next,无脑安装. 默认安装在c盘
(2)window+R,打开终端(黑窗口),输入cmd,打开电脑终端
(3)输入node -v查看node是否安装以及node的版本
Node.js 是一个跨平台 JavaScript 运行环境,使开发者可以搭建服务器端的 JavaScript 应用程序
概念: 使用 Node.js 编写后端程序 / 支持前端工程化
后端程序:提供接口和数据,网页资源等
前端工程化:对代码压缩,转译,整合(使用各种工具,提升效率)
(1)以前js的运行环境是浏览器,node也是js的运行环境
(2)node的作用可以搭建服务,开发后台接口,可以实现前端工程化 (代码的压缩、编译等
首先:浏览器能执行 JS 代码,依靠的是内核中的 V8 引擎(C++ 程序)
其次:Node.js 是基于 Chrome V8 引擎进行封装(运行环境)
区别:都支持 ECMAScript 标准语法,Node.js 有独立的 API
注意: Node.js 环境没有 DOM 和 BOM 等
①方法1打开终端
直接在vscode中右键文件–>打开集中终端
②方法2打开终端
在文件所在位置单机文件位置,输入cmd,回车,打开终端
③方法3打开终端
在文件所在位置shift+右键
fs 模块 - 读写文件
模块:类似插件,封装了方法/属性
fs 模块:封装了与本机文件系统进行交互的,方法/属性
语法:
①方法一 :加一个’utf-8’
②方法2:toString转换
目标7: node中的内置path模块
作用:读写指定路径下的文件
备注:在读写文件是不建议采用相对路径的写法,是不严格的写法,有可能会出错,因为它会以当前终端所在的目录为参考点去寻找,会出现找不到的情况如何解决?
采用绝对路径的写法,绝对路径怎么获取的? 通过 dirname可以获取如何用绝对路径拼接文件的路径呢?通过path模块中的join方法
//需求:在03文件夹下的index.js文件中读取test.js文件中读取test.txt的内容
const fs = require('fs')
//下面的这种相对路径的写法,是不严格的写法,有可能会出错,因为它会以当前终端所在的目录为参考点去寻找,会出现找不到的情况,
//因此不建议采用相对路径的写法,如何解决?
// 用node中的path模块去解决
//node中有一个全局变量
//node中有一个全局变量dirhame.可以获取目前运行文件的绝对路径
// console.log(__dirname, 'buiuhhhhhhhhh')// (D:\资料U盘\2023.5.7Node.js\2023.5.7_Node.js\03\index.js:8:13)
//解决方案:就是用绝对路径拼接文件的路径
//引入path模块
const path = require('path')
//底下的代码是在用绝对路径拼接文件的路径
const filePath = path.join(__dirname, '../', 'test.txt')
// const filePath = path.join('D:\资料U盘\2023.5.7Node.js\2023.5.7_Node.js\03', '../', 'test.txt')
fs.readFile('../test.txt', 'utf-8', (err, data) => {
if (err) {
console.log(err)
} else {
console.log(data)
}
})
目标1: 时钟案例
需求: 将public文件夹下的index.html文件和indexjs读取出来,并将换行符和回车符去掉,并写入到dist文件夹下
第一步: 先将public文件夹下的index.html文件内容读取出来
第二步: 将html文件的内容写入到dist文件夹下
第三步:将public下的indexjs内容读取出来,并将换行符和回车符去掉,要去和html文件的内容进行合并,一次性写入到dist文件夹下
// 引入fs模块
const { log } = require('console')
const fs = require('fs')
// 引入path模块
const path = require('path')
// console.log(__dirname, '123456')//D:\资料U盘\2023.5.7Node.js\2023.5.8_Node.js\04-时钟案例
const htmlPath = path.join(__dirname, 'public', 'index.html')
// 读取public下的index.html
fs.readFile(htmlPath, 'utf-8', (err, data) => {
if (err) {
console.log('失败了')
} else {
// console.log(data)
//拿到文件内容之后要去除文件默认的回车符以及换行符
// const htnmlstr=data.replace('目标内容 ,替换成什么')
//通过正则全局找到回车符和换行符进行替换(对文件进行简单的压缩)
const htmlStr = data.replace(/[\r\n]/g, ' ')
// console.log(htmlStr)
//html文件的内容读取成功之后,继续读照js文件的内容
fs.readFile(path.join(__dirname, 'public', 'index.js'), 'utf-8', (err, data) => {
// if (err) {
// console.log(失败了)
// } else {
// console.log(data)
const jsStr = data.replace(/[\r\n]/g, '')
//要将读取出的js内容添加上script标签
const jsScript = `${jsStr}`
console.log(jsScript)
//将读取出来的html文件的内容写入到dist文件下
fs.writeFile(path.join(__dirname, 'dist', 'index.html'), htmlStr + jsScript, err => {
if (err) {
console.log(失败了)
} else {
console.log(成功了)
}
})
// }
})
}
})
写入到一个新的文件夹内的js
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>时钟案例</title>
<style>
html,
body {
margin: 0;
padding: 0;
height: 100%;
background-image: linear-gradient(to bottom right, rgb(154, 231, 119), rgba(153, 202, 243, 0.521));
}
.box {
width: 400px;
height: 250px;
background-color: rgba(255, 255, 255, 0.6);
border-radius: 6px;
position: absolute;
left: 50%;
top: 40%;
transform: translate(-50%, -50%);
box-shadow: 1px 1px 10px #fff;
text-shadow: 0px 1px 30px white;
display: flex;
justify-content: space-around;
align-items: center;
font-size: 70px;
user-select: none;
padding: 0 20px;
-webkit-box-reflect: below 0px -webkit-gradient(linear, left top, left bottom, from(transparent), color-stop(0%, transparent), to(rgba(250, 250, 250, .2)));
}
</style>
</head>
<body>
<div class="box">
<div id="HH">00</div>
<div>:</div>
<div id="mm">00</div>
<div>:</div>
<div id="ss">00</div>
</div>
</body>
</html>
<script>window.addEventListener('load', function () { console.log('测试-网页加载完成了'); clock(); setInterval(clock, 1000); }); function clock() { console.log('测试-时钟函数调用了'); let dt = new Date(); let HH = dt.getHours(); let mm = dt.getMinutes(); let ss = dt.getSeconds(); console.log(dt, HH, mm, ss); document.querySelector('#HH').innerHTML = padZero(HH); document.querySelector('#mm').innerHTML = padZero(mm); document.querySelector('#ss').innerHTML = padZero(ss); }; function padZero(n) { console.log(n); return n > 9 ? n : '0' + n; }</script>
避免用这些特殊的端口号,80,3000,8080,3306,已被其他服务程序占用
const http = require('http')
const server = http.createServer()
server.on('request', (req, res) => {
res.end('hello, world')
})
server.listen(3000, () => {
console.log('web服务已启动')
})
// 引入http模块
const http = require('http')
// 创建服务对象
const server = http.createServer()
// 监听客户端的请求,发送内容给客户端
server.on('request', (req, res) => {
// 通过req可以拿到前端访问的地址,包括携带参数
// 通过res.end给客户端发送内容
// res.end('succeed')
// res.end('hello,world')
// //由于服务端响应给客户端的是中文的话会乱码,需要设置响应头
// text/html代表返回的是 普通文本格式
res.setHeader('Content-Type', 'text/html;charset=utf-8')
res.end('吃饭了')
})
// 监听服务的端口号
server.listen(3001, () => {
console.log('web服务已启动')
})
备注: 如果服务端返回给客户端的内容是中文的话,会出现乱码情况,如何解决?
目标4: 在客户端输入服务地址获取省份数据,服务端要将数据响应回去
思路: 如果客户端的请求地址包含/api/province的话,则去读取data文件夹下的provice.json文件中的内容,并返回给客户端
(1)如果服务端响应给客户端的是数组或对象等,响应头需要设置为application/jsonres.setHeader(‘Content-Type’, ‘application/json;charset=utf-8’)
(2)如果服务端响应给客户端的是普通的文本或者html片段,则响应头设置为text/htmlres.setHeader(‘Content-Type’, ‘text/html;charset=utf-8’)
日标5: 通过node写一个查询市的接口
http://localhost:3000/api/city?pname=%E8%BE%BD%E5%AE%81%E7%9C%81第一步: 在服务端判断客户端发送的请求地址是不是”/api/city
备注: 重启服务之前,先ctrl+c快捷键先终止服务
步骤:
1.基于 http 模块,创建 Web 服务
2. 使用 req.url 获取请求资源路径,并读取 index.html 里字符串内容返回给请求
3.其他路径,暂时返回不存在的提示
4.运行 Web 服务,用浏览器发起请求
CommonJS 模块是为 Node.js 打包 javaScript 代码的原始方式。Node.js 还支持浏览器和其他 JavaScript 运行时使用的 ECMAScript 模块标准.在 Node.js 中,每个文件都被视为一个单独的模块。
需求:定义utils.js 模块,封装基地址和求数组总和的函数
使用:
const baseUrl = 'http:baidu.com'
const getSum = (arr) => arr.reduce((sum, val) => { return sum += val }, 0)
// 导出两个常量:
module.exports = {
baseUrlPath: baseUrl,
getArraySum: getSum
}
const obj = require('./utils.js')//引入自定义模块
console.log(obj)
需求:封装并导出基地址和求数组元素和的函数
默认标准使用:
es6需要配置一个package.json
导出:export default{}
// 这就是一个自定义的模块
const baseUrl = 'http:baidu.com'
const getSum = (arr) => arr.reduce((sum, val) => { return sum += val }, 0)
// 通过es6模块化默认导出的方式导出两个常量
export default {
baseUrlPath: baseUrl,
getArraySum: getSum
}
导入: import 变量名 from ‘模块名或路径’
import obj from './utils.js' //引入自定义模块
console.log(obj)
const result = obj.getArraySum([2, 34, 55])
console.log(result)
注意: Node.js 默认支持 CommonJS 标准语法
如需使用 ECMAScript 标准语法,在运行模块所在文件夹新建 package.json 文件,并设置{“type” :“module”}
需求:封装并导出基地址和求数组元素和的函数
命名标准使用:
es6需要配置一个package.json
// es6标准按需导出
export const baseUrl = 'http:baidu.com'
export const getSum = (arr) => arr.reduce((sum, val) => { return sum += val }, 0)
// es6标准按需导入
// 注意:按需导入的是偶是什么名字,按需导入的时候就是什么名字
import { getSum } from './utils.js'
const result = getSum([2, 4, 6])
console.log(result)
按需加载,使用命名导出和导入
全部加载,使用默认导出和导入
1.什么是包?
将模块,代码,其他资料聚合成的文件夹
2. 包分为哪 2 类呢?
项目包:编写项目代码的文件夹
软件包: 封装工具和方法供开发者使用
3.package.json 文件的作用?
记录软件包的名字,作者,入口文件等信息
4.导入一个包文件夹的时候,导入的是哪个文件?
默认 index.js 文件,或者 main 属性指定的文件
npm 简介
npm 是 Nodejs 标准的软件包管理器
在 2017 年 1 月时,npm 仓库中就已有超过 350000 个软件包,这使其成为世界上最大的单一语言代码仓库,并且可以确定几乎有可用于一切的软件包。
它起初是作为下载和管理 Node.js 包依赖的方式,但其现在也已成为前端JavaScript 中使用的工具。
是管理各种各样的插件的,供开发者下载安装使用,在安装node时已经顺带安装了npm,因此,无序单独安装,yarn也是一个包管理工具,需要单独安装 (vue阶段学习)
使用步骤:
第一步: 如果文件夹中没有packagejson文件,则执行命令 npm init -y生成package,json文件
第二步: 通过npm install ‘软件包名’ 下载安装包
第三步:使用软件包
观察:安装完包之后文件夹发生了什么变化?
(1)多出来一个node modules文件夹,里面存放的是下载的包
(2)多出了一个package-lock,json文件,起到版本固化的一个作用
(3)安装完软件包之后,package.json文件中也发生了变化: 多出了一个dependencies配置项,下载的包的版本在这里可以查看到,用来记录下载包的信息的
(4)使用软件包:
第一种引入方式: CommonJS的导入规范let dayjs = require(dayjs) //注意: 默认读取的是node modules文件夹下面的包
第二种方式:es6的导入方式
import dayjs from ‘dayjs’
但需要在package.json文件中第一行加入 “type”: “module”,
①新建一个02npm文件夹–>在集成终端中打开–>输入命令npm init -y
②输入命令 npm i dayjs
③在入口文件中使用软件包,入口文件在package.json文件中看
④默认读取的是node_modules文件夹下的dayjs包
//在入口文件中使用软件包,入口文件在package.json文件中看
// let dayjs = require('dayjs')//默认读取的是node_modules文件夹下的dayjs包
// 第二种方式: es6的导入方式
import dayjs from 'dayjs'
//调用dayjs软件包中的format方法进行日期格式的转化
const result = dayjs().format("YYYY-MM-DD")
console.log(result)
①一次性安装项目所需要的安装包,输入命令npm i(简写)
前提:在package.json有要安装的包的版本信息
输入命令npm i
全局软件包就是在电脑中的其它项目里也可以去使用,而不只是限于一个项目;
举例1: nodemon全局包可以替代node命令,检查代码的更改
举例2: vue的脚手架也是一个全局包
命令: npminodemon -g (g 代表安装到全局环境中)
第一种方式:
第一步: npm config set registry=http://registry.npm.taobao.org
第二步: npm config get registry 查看镜像源命令
第二种方式: 通过nrm镜像源插件管理,进行切换
npm i nodemon -g
全局包安装了之后,内容更改之后直接就会输出结果
1.本地软件包和全局软件包区别?
本地软件包,作用在当前项目,封装属性和方法
全局软件包,本机所有项目使用,封装命令和工具
2. nodemon 作用?
替代 node 命令,检测代码更改,自动重启程序
3. nodemon 怎么用?
先确保安装 npm i nodemon -g
使用 nodemon 执行目标 js 文件
Node.js 模块化:
概念:每个文件当做一个模块,独立作用域,按需加载
使用:采用特定的标准语法导出和导入进行使用
备注:如何删除包?
Inpm uninstall '包名’卸载区部包,node modules文件夹下的包会被移除
npm uninstal ‘包名’-g 移除全局包
概念:使用 express 本地软件包,快速搭建 Web 服务(基于 http 模块)
功能: 提供数据接口
提供网页资源等
node中的express第三方插件学习
作用: 是对http模块做了进一步封装,功能更加强大,可以快速创建一个web服务
第一步: 通过npm init -y 在文件夹下生成一个packagejson文件
第二步: 安装包: npmiexpress
第三步:利用express插件创建一个web服务
//引入express第三方包
const express = require('express')
//创建服务对象
const server = express()
//监听客户端发起的get请求
server.get('./', (req, res) => {
//在req可以获取客户端发起请求的地址和参数
//服务端做出响应
res.send('你好')
})
//当浏览器地址栏的请求地址匹配不到相对应的接口地址时,响应一个404
server.all('*', (req, res) => {
//在req可以获取客户端发起请求的地址和参数
//服务端做出响应
res.send('你好110')
})
//监听端口号
server.listen(3003, () => {
console.log('web服务启动了')
})
高频面试题
什么是浏览器的源策略?
同源策略是浏览器的一种安全机制,防止一些非法网站恶意攻击,盗取信息当协议、域名、端口号都一致时视为同源,只要有一个不一致就是非同源
1.什么是同源策略?
限制一个源对另外一个源资源交互
2.同源策略限制的是?
限制 AJAX 只能访问同源 URL
3.什么情况下是同源?
网页加载时所在源,和 AJAX 请求时的源(协议,域名,端口号)全部相同即为同源
什么是跨域?
由于浏览器同源策略的限制只要前端服务地址和要访问的后端服务地址中,协议、域名、端口号有一个不一致,就会造成跨域问题
如何解决跨域问题?
方式1: jsonp的方式(已过时,只支持get请求)原理就是script标签的src属性不受同源策略的限制
方式2:cors的方式(开发环境下后端的解决方案)
(1)手动添加响应头解决跨域
res.setHeader(Access-Control-Allow-Origin’,‘*’) //这个配置指的是所有源均可以访问该服务
(2)通过第三方插件cors自动添加响应头,本质还是上面的响应头配置
方式3: 反向代理的方式(后面项目阶段学)
备注:访问自己本地后台服务两种方式:
方式1: http://localhost:3003
方式2: http://1127.0.0.1:3003
跨域解决补充方案:
如果项目到线上时,还是通过cors解决跨域,还不不安全,因此,cors的解决方案一般只限于开发环境下,项目上线也就是部署到生产环境时需要通过其他方案:原理:既然前后端存在非同源情况,在生产环境又不能用cors解决,那可以将前端项目资源放大服务器所在文件夹下,客户端直接访问服务器下的资源,那就是同源的,不存在跨域
//express插件中的static方法会默认去public文件夹下去寻找客户端请求的资源,如果存在就会将资源文件返回回去。
server.use(express.static(‘./public’))