Node.js入门
Node.js是什么
Node.js
是一个跨平台的 JavaScript 运行环境,主要使用场景有:
- 编写后端程序:充当服务器,对外提供Web服务(接口、数据、网页资源等)
- 前端工程化:对代码进行压缩,转译和整合
浏览器和Node环境的对比
Node.js
内部封装了 Chrome V8
引擎,因此可以像浏览器一样运行 JS 代码:
bash
node xxx.js
浏览器和 Node.js 都支持 ECMAScript 标准语法,Node 中没有 DOM 对象和 BOM 对象,但自身又封装了一些特殊的 API
Node常见内置模块
fs 模块
:用来读写文件path 模块
:用来处理文件路径http 模块
:对外提供Web服务
Node中相对路径的问题
在 Node 中运行 JavaScript 代码时,代码中的相对路径总是根据 运行命令的终端
所在路径来查找的,在不同的终端下可能会无法找到目标文件
Node 推荐使用绝对路径,在 JS 代码中,先使用 __dirname__
获取当前文件所在绝对路径,然后调用 path.join(__dirname__,相对路径)
方法拼接成目标文件的真实绝对路径
eg.使用Node对外提供web服务
js
// 1.引入相关内置模块
const http = require("http");
const fs = require("fs");
const path = require("path");
// 2.创建server对象,用来对外提供web服务
const server = http.createServer();
// 3.监听请求并处理
server.on("request", (req, res) => {
if (req.url === "/api/province") {
fs.readFile(path.join(__dirname, "./data/province.json"), (err, data) => {
// 解决中文乱码
res.setHeader("Content-Type", "application/json;charset=utf-8");
// 返回响应数据
res.end(data.toString());
});
} else {
res.end("<h1>404</h1>");
}
});
// 4.启动web服务
server.listen(3000, () => {
console.log("web服务已启动...");
});
eg.模拟前端工程化
js
// 模拟前端工程化中的代码压缩
// 把 public/index.html 里的回车/换行符去掉,写入到 dist/index.html 中
const fs = require("fs");
const path = require("path");
// 1.读取原文件,利用replace方法替换代码中的回车和换行
fs.readFile(path.join(__dirname, "./public/index.html"), (err, data) => {
if (err) return console.error(err);
// 读取的文件内容
const htmlStr = data.toString();
// 压缩后的字符串
const str = htmlStr.replace(/[\r\n]/g, "");
// 2.将压缩后的代码写入一个新文件中
fs.writeFile(path.join(__dirname, "./dist/index.html"), str, (err) => {
if (err) return console.error(err);
console.log("压缩成功");
});
});
模块化
什么是模块化
模块化
:可以把项目中的每个文件都看做是一个模块。模块之间彼此独立,使用特定语法进行导入导出
模块化的好处
:
- 提高代码复用性
- 实现按需加载
- 作用域独立
CommonJS标准
和 ECMAScript标准
是两种常见的模块导入导出的语法标准
CommonJS标准
CommonJS标准
是 Node 默认的导入导出语法规范
js
const checkUsername = (uname) => uname.length >= 8;
const checkPwd = (pwd) => pwd.length >= 6;
// 导出一个对象
module.exports = {
checkUsername,
checkPwd,
};
js
// 对于导入的对象,可以直接解构赋值
const { checkUsername, checkPwd } = require("./utils/check.js");
console.log(checkUsername("pc666888"));
console.log(checkPwd("123456"));
对于内置模块,导入时只写模块名就行;对于自定义模块,导入时需要写文件完整路径(包括后缀)
ECMAScript 标准
ECMAScript标准
是 ES6 新增的导入导出语法,在现代前端工程化中最为常用
ES6模块的设计思想是尽量的静态化,使得 编译时
就能确定模块的依赖关系,以及输入和输出的变量。CommonJS模块 和 AMD模块,都只能在 运行时
确定这些东西
要在 Node.js 中使用 ECMAScript 标准语法,需要在项目根目录中新建
package.json
文件,并设置{"type":"module"}
属性
默认导入导出
js
const checkUsername = (uname) => uname.length >= 8;
const checkPwd = (pwd) => pwd.length >= 6;
// 导出一个对象
export default { checkUsername, checkPwd };
js
// 对于导入的对象,必须先用一个变量接收
import check from "./utils/check.js";
const { checkUsername, checkPwd } = check;
console.log(checkUsername("pc666888"));
console.log(checkPwd("123456"));
一个模块只能有一个默认导出语句
默认导出不能直接解构赋值,必须用一个变量接收,变量名是可以自定义的
命名导入与导出
使用 命名导入/导出
可以实现模块的按需加载:
js
// 写法一:单独导出
// export后的修饰定义语句可以是:函数、类或普通变量
export const checkUsername = (uname) => uname.length >= 8;
export const checkPwd = (pwd) => pwd.length >= 6;
// 写法二:统一导出为对象
const checkUsername = (uname) => uname.length >= 8;
const checkPwd = (pwd) => pwd.length >= 6;
export { checkUsername, checkPwd };
js
// 对于导入的对象,可以直接解构赋值
import { checkUsername, checkPwd } from "./utils/check.js";
console.log(checkUsername("pc666888"));
console.log(checkPwd("123456"));
在html引入js模块
html
<!-- defer (默认)异步模块加载模式,等待html全部渲染完再执行 -->
<script type="module" src="./foo.js" defer></script>
<!-- async 异步模块加载模式,加载完就执行 -->
<script type="module" src="./foo.js" async></script>
包管理
什么是软件包
软件包
:本质就是一个文件夹,内部封装了工具和方法供开发者使用。根目录中必须要有 package.json
文件(记录软件包的名字,作者,入口文件,依赖包等信息)
软件包的分类
:
本地软件包
:仅在当前项目内使用,封装属性和方法,存在于项目根目录下的node_modules
中全局软件包
:本机所有项目都可能会使用,封装命令和工具,存在于系统全局位置(如hexo命令)
在导入三方软件包时,默认入口文件是 index.js,我们也可以在
package.json
中使用main
属性自定义入口文件的位置
使用npm管理软件包
命令 | 功能 | 备注 |
---|---|---|
npm init -y |
初始化一个 package.json 文件 |
-y 跳过填写信息 |
npm install <module> |
安装指定依赖包 | -g 全局安装 | --save-dev 安装开发时的依赖 |
npm install |
安装所有依赖包 | 通常用来生成 node_modules |
同源和跨域
什么是同源策略
同源策略
是浏览器中的一个重要的安全策略,它用于限制一个源的文档或者它加载的脚本如何才能与另一个源的资源进行交互,从而帮助阻隔恶意文档,减少被攻击的可能性
源
:特指 URL 中的 协议、域名和端口号
部分
同源
:如果两个URL的 协议、域名和端口号
都相同,那么这两个URL就是同源的
什么是跨域访问
在浏览器中,一个网页的脚本通过 ajax 请求另一个源的资源时,如果 网页所在源
和 ajax 请求的源
(协议、域名或端口号)不完全相同,就会发生 跨域访问
,导致请求失败
解决跨域问题
开发中-CORS跨域资源共享
前后端分离的项目,不在同一个源开发,为了保证正常的数据通信,可以采用 CORS(Cross-Origin Resource Sharing)跨域资源共享
机制
CORS的实现过程
:通过在服务端设置 Access-Control-Allow-Origin
响应头字段,标识允许跨域访问的源地址;浏览器在收到这个响应头后,就会允许跨域访问并将响应数据返回给前端页面
上线后-同源访问
把前端项目和后端项目部署到同一个源下,在保证安全性的前提下直接避免跨域访问的问题