1. Node.js 模块化
1.1 CommonJS 标准
utils.js
/*** 目标:基于 CommonJS 标准语法,封装属性和方法并导出*/
const baseURL = "http://hmajax.itheima.net";
const getArraySum = (arr) => arr.reduce((sum, item) => (sum += item), 0);module.exports = {baseURL,getArraySum,
};
index.js
/*** 目标:基于 CommonJS 标准语法,导入工具属性和方法使用*//* 模块化:每个文件都是独立的模块,需要标准语法导出和导入进行使用CommonJS 标准 - 导出和导入模块➢ 导出:module.exports = {}➢ 导入:require('模块名或路径')➢ 内置模块,直接写名字。例如:fs,path,http等➢ 自定义模块,写模块文件路径。例如:./utils.js
*/// 解构导入的数据
// const { baseURL, getArraySum } = require("./utils");
const { baseURL, getArraySum } = require("./utils.js");console.log(baseURL); // http://hmajax.itheima.net
console.log(getArraySum([1, 5, 8])); // 14
1.2 ECMAScript 标准 - 默认导出和导入
utils.js
/*** 目标:基于 ECMAScript 标准语法,封装属性和方法并"默认"导出*/
const baseURL = "http://hmajax.itheima.net";
const getArraySum = (arr) => arr.reduce((sum, item) => (sum += item), 0);export default {baseURL,getArraySum,
};
package.json
{"type": "module"
}
index.js
/*** 目标:基于 ECMAScript 标准语法,"默认"导入,工具属性和方法使用*//* 1. ECMAScript 标准 - 默认导出和导入模块➢ 导出:export default {}➢ 导入:import 变量名 from '模块名或路径'2. Node.js 切换模块标准为 ECMAScript➢ 运行模块所在文件夹,新建 package.json 并设置{ "type" : "module" }
*/import obj from "./utils.js";
console.log(obj.baseURL); // http://hmajax.itheima.net
console.log(obj.getArraySum([1, 4, 7])); // 12
1.3 ECMAScript 标准 - 命名导出和导入
utils.js
/*** 目标:基于 ECMAScript 标准语法,封装属性和方法并"命名"导出*/
export const baseURL = "http://hmajax.itheima.net";
export const getArraySum = (arr) => arr.reduce((sum, item) => (sum += item), 0);
package.json
{"type": "module"
}
index.js
/*** 目标:基于 ECMAScript 标准语法,"命名"导入,工具属性和方法使用*//* ECMAScript 标准,命名导出和导入的语法➢ 导出:export 修饰定义的语句➢ 导入:import { 同名变量 } from '模块名或路径'按需加载,使用命名导出和导入全部加载,使用默认导出和导入
*/import { getArraySum, baseURL } from "./utils.js";
console.log(baseURL); // http://hmajax.itheima.net
console.log(getArraySum([1, 5, 8, 12, 234])); // 260
2. 软件包
/* 1. 什么是包?➢ 将模块,代码,其他资料聚合成的文件夹2. 包分为哪 2 类呢?➢ 项目包:编写项目代码的文件夹➢ 软件包:封装工具和方法供开发者使用3. package.json 文件的作用?➢ 记录软件包的名字,作者,入口文件等信息4. 导入一个包文件夹的时候,导入的是哪个文件?➢ 默认 index.js 文件,或者 main 属性指定的文件
*/
3. npm 软件包管理器
3.1 npm - 软件包管理器
/*** 目标:使用 npm 下载 dayjs 软件包来格式化日期时间* 1. (可选)初始化项目清单文件,命令:npm init -y* 2. 下载软件包到当前项目,命令:npm i 软件包名称* 3. 使用软件包*//*npm config set registry xxx 这个命令用于设置 npm(Node Package Manager)的注册表地址默认情况下,npm 使用官方的 npm 注册表 (https://registry.npmjs.org),但有时为了加快下载速度或访问某些特定的包,用户可能会选择使用镜像源。1. 将 npm 的注册表设置为一个镜像源(在中国境内可能更快)npm config set registry http://registry.npmmirror.com2. 安装 dayjs 这个日期处理库; i - installnpm i dayjs
*//* 1. npm 软件包管理器作用?➢ 下载软件包以及管理版本2. 初始化项目清单文件 package.json 命令?➢ npm init -y3. 下载软件包的命令?➢ npm i 软件包名字4. 下载的包会存放在哪里?➢ 当前项目下的 node_modules 中,并记录在 package.json 中
*/const dayjs = require("dayjs");
const res = dayjs().format("YYYY-MM-DD");
console.log(res); // 2024-12-12
3.2 npm - 安装所有依赖
/*** 目标:安装所有依赖软件包* 场景:一般拿到别人的项目后,只有 package.json 缺少 node_modules 时需要做* 语法:在当前项目终端下,输入命令:npm i* 效果:会根据 package.json 记录的所有包和版本开始下载*//* 1. 当项目中只有 package.json 没有 node_modules 怎么办?➢ 当前项目下,执行 npm i 安装所有依赖软件包2. 为什么 node_modules 不进行传递?➢ 因为用 npm 下载比磁盘传递要快
*/// 格式化日期
const dayjs = require("dayjs");
const nowDateStr = dayjs().format("YYYY-MM-DD");
console.log(nowDateStr); // 2024-12-12// 求数组里最大值
const _ = require("lodash");
console.log(_.max([1, 2, 8, 3, 4, 5])); // 8
4. npm 全局软件包 nodemon
/*** 目标:使用 nodemon 全局软件包,检测文件变化,自动重启程序* 语法:* 1. 安装 nodemon 全局软件包,命令:npm i nodemon -g* 2. 使用 nodemon 来执行目标 js 文件* 体验:启动后,修改代码,保存后观察终端效果*//* 1. 本地软件包和全局软件包区别?➢ 本地软件包,作用在当前项目,封装属性和方法➢ 全局软件包,本机所有项目使用,封装命令和工具2. nodemon 作用?➢ 替代 node 命令,检测代码更改,自动重启程序3. nodemon 怎么用?➢ 先确保安装 npm i nodemon -g➢ 使用 nodemon 执行目标 js 文件
*/// 格式化日期
const dayjs = require("dayjs");
const nowDateStr = dayjs().format("YYYY-MM-DD");
console.log(nowDateStr);// 求数组里最大值
const _ = require("lodash");
console.log(_.max([1, 10, 2, 3, 4, 55]));
5. Node.js 总结
/*** 总结:* Node.js模块:* 概念:每个文件就是一个模块,独立作用域,按需加载,需使用特定语法导出导入* CommonJS 标准语法:* 导出:module.exports = {}* 导入:require('模块名或路径')* ECMAScript 标准语法:* 默认导出:export default {}* 默认导入:import 变量名 from '模块名或路径'* 命名导出:export 修饰定义语句* 命名导入:import { 同名变量 } from '模块名或路径'** Node.js包:* 概念:把模块文件,代码文件,其他资料聚合成一个文件夹* 项目包:编写项目需求和业务逻辑的文件夹* 软件包:封装工具/方法的文件夹(一般用 npm 管理)* 本地软件包:封装属性/方法,在当前项目中使用,例如:dayjs,lodash* 全局软件包:封装工具/命令,在本机中使用,例如:nodemon** 常用命令:* 执行 js 文件:node xxx* 初始化 package.json: npm init -y* 下载本地软件包:npm i 软件包名* 下载全局软件包:npm i 软件包名 -g* 删除软件包:npm uni 软件包名*/
6. Express 搭建 Web 服务
/* Express - 框架使用 express 本地软件包,快速搭建 Web 服务(基于 http 模块)功能:1. 提供数据接口 2. 提供网页资源等
*/// 1. 下载 express 软件包
const express = require("express");// 2. 导入并创建 Web 服务对象
const server = express();// 3. 监听请求的方法和请求的资源路径
server.get("/", (req, res) => {res.send("哦耶 express");
});// 4. 监听任意请求的方法和请求的资源路径
server.all("*", (req, res) => {res.status(404);res.send("您访问的资源不存在");
});// 5. 监听端口号,启动 Web 服务
server.listen(3000, () => {console.log("启动成功成功");
});
7. 获取省份列表 - 接口开发
/*** 目标:基于 express 软件包,开发提供省份列表的数据接口* 要求:get 请求方法,/api/province 的请求路径*/const fs = require("fs");
const path = require("path");
const express = require("express");
const server = express();// 监听 get 请求方法,
// 监听资源路径 /api/province,
// 读取 province.json 省份数据返回
server.get("/api/province", (req, res) => {fs.readFile(path.join(__dirname, "/data/province.json"), (err, data) => {if (err) {console.log(err);} else {res.send(data.toString());}});
});server.all("*", (req, res) => {res.status(404);res.send("你要访问的资源路径不存在");
});server.listen(3000, () => {console.log("Web 服务已启动");
});
8. 跨域以及解决方案
8.1 浏览器的同源策略
/*** 目标:了解浏览器中的同源策略* 同源策略:是一种安全策略,限制一个源的文档/脚本与另外一个源的资源交互** 好处:保护网站的安全,减少被攻击的媒介* 限制:浏览器限制 AJAX 只能访问同源的 URL 网址!** 源:指的 URL 中的协议,域名,端口号* 同源:网页加载所在的源,与 AJAX 请求的源完全相同即为同源*/
8.2 跨域问题
/* 跨域访问:网页所在源和 AJAX 请求的源(协议,域名,端口号)不完全相同,就发生跨域访问
*/
8.3 跨域问题 - 解决方案1 - CORS
/* 跨域问题 - 解决方案1 - CORS目标:前后端分离的项目,前端和后端不在一个源,还要保证数据通信解决:采用 CORS (跨域资源共享),一种基于 HTTP 头的机制,该机制通过允许服务器标示除了它自己以外的其他源(域、协议或端口),使得浏览器允许这些源访问加载自己的资源步骤:1. 下载 cors 本地软件包2. 导入 cors 函数3. 使用 server.use() 给 Web 服务添加插件功能4. 把 cors 函数调用传入给 Web 服务,启动测试1. 为什么要解决跨域问题?➢ 因为前后端分离的项目,不在同一个源去开发项目➢ 需要保证数据之间通信2. 跨域问题如何解决?➢ 让后端开启 CORS 跨域资源共享➢ 在响应头设置 Access-Control-Allow-Origin: *
*/// 2. 导入 cors 函数
const cors = require("cors");
// 3. 使用 server.use() 给 Web 服务添加插件功能
server.use(cors());
8.4 跨域问题 - 解决方案2 - 同源访问
/* 跨域问题 - 解决方案2 - 同源访问目标:开发环境用 cors,上线部署关闭 cors,并采用同源访问方式做法:让后端 Web 服务既可以提供数据接口,也可以返回网页资源好处:安全,后端的接口不允许非同源来访问1. CORS 只适用于什么阶段的项目?➢ 本地开发阶段项目2. 项目上线,如何解决跨域问题?➢ 把前端项目和后端项目部署到同一个源下访问
*/// 暴露指定的文件夹,让前端可以直接拼接路径和资源名字来访问
server.use(express.static(path.join(__dirname, "public")));