Node.js

纯属个人易忘点的笔记,素材来源于知播渔江哥:www.it666.com,良心教师质量教师,有意向走前端全栈的快快点击网址开始学习吧

1.什么是Node.js

Node.js 是一个基于"Chrome V8 引擎" 的JavaScript “运行环境”

V8引擎是一款专门解释和执行JS代码的虚拟机, 任何程序只要集成了V8引擎都可以执行JS代码

NodeJS不是一门编程语言, NodeJS是一个运行环境,由于这个运行环境集成了V8引擎, 所以在这个运行环境下可以运行我们编写的JS代码, 这个运行环境最大的特点就是提供了操作"操作系统底层的API", 通过这些底层API我们可以编写出网页中无法实现的功能(诸如: 打包工具, 网站服务器等)

1.Node环境和浏览器环境区别
NodeJS环境和浏览器环境一样都是一个JS的运行环境, 都可以执行JS代码. 但是由于宿主不同所以特点也有所不同

1.1内置对象不同

  • 浏览器环境中提供了window全局对象
  • NodeJS环境中的全局对象不叫window, 叫global

1.2this默认指向不同

  • 浏览器环境中全局this默认指向window
  • NodeJS环境中全局this默认指向空对象{}

1.3API不同

  • 浏览器环境中提供了操作节点的DOM相关API和操作浏览器的BOM相关API
  • NodeJS环境中没有HTML节点也没有浏览器, 所以NodeJS环境中没有DOM/BOM

2.npm,nrm,cnpm

  • npm(node package manager)是nodejs的包管理器,用于node插件管理(包括安装、卸载、管理依赖等)
  • nrm只是单纯的提供了几个常用的下载包的uri地址,并能够这让我们在这几个地址之间,很方便的进行切换,但是我们每次装包的时候,使用的装包工具都是npm
  • cnpm类似于npm,也是一个服务器,只是此服务器在国内镜像服务器,下载包速度快,但是此服务器中的包也是从npm服务器中copy过来的,最终包都是npm上的包

npm,nrm,cnpm 常用命令:
1.NPM包安装方式

全局安装

(一般用于安装全局使用的工具, 存储在全局node_modules中)
npm install -g 包名 (默认安装最新版本)
npm uninstall -g 包名
npm update -g 包名 (更新失败可以直接使用install)

本地安装

(一般用于安装当前项目使用的包, 存储在当前项目node_modules中)
npm install 包名
npm uninstall 包名
npm update 包名
2.初始化本地包
npm init -> 初始化package.json文件
npm init -y -> 初始化package.json文件
npm install 包名 --save
npm install 包名 --save-dev
**包描述文件 package.json, 定义了当前项目所需要的各种模块,以及项目的配置信息(比如名称、版本、许可证等元数据)。
npm install 命令根据这个配置文件(

    "scripts": {
    "test": "npx webpack ./index.js"
  }  //npm run test =npm run npx webpack ./index.js
),自动下载所需的模块,也就是配置项目所需的运行和开发环境
注意点:package.json文件中, 不能加入任何注释**
- dependencies:生产环境包的依赖,一个关联数组,由包的名称和版本号组成
- devDependencies:开发环境包的依赖,一个关联数组,由包的名称和版本号组成
1.将项目拷贝给其它人, 或者发布的时候, 我们不会将node_modules也给别人, 因为太大
2.因为有的包可能只在开发阶段需要, 但是在上线阶段不需要, 所以需要分开指定
npm i               所有的包都会被安装
npm i --production  只会安装dependencies中的包
npm i --development  只会安装devDependencies中的包

npm install -g nrm 安装NRM nrm --version 查看是否安装成功 npm ls
查看允许切换的资源地址 npm use taobao 将下载地址切换到淘宝

PS:淘宝资源地址和国外的地址内容完全同步,。淘宝镜像与官方同步频率目前为 10分钟 一次以保证尽量与官方服务同步 npm install
cnpm -g –registry=https://registry.npm.taobao.org 安装CNPM cnpm -v
查看是否安装成功 使用方式同npm, 例如: npm install jquery 变成cnpm install jquery 即可

1.什么是模块?
1.1浏览器开发中的模块 在浏览器开发中为了避免命名冲突, 方便维护等等 我们采用类或者立即执行函数的方式来封装JS代码, 来避免命名冲突和提升代码的维护性 其实这里的一个类或者一个立即执行函数就是浏览器开发中一个模块
let obj = {
模块中的业务逻辑代码
};
;(function(){
模块中的业务逻辑代码
window.xxx = xxx;
})();
存在的问题: 没有标准没有规范

1.2NodeJS开发中的模块 NodeJS采用CommonJS规范实现了模块系统

1.3CommonJS规范 CommonJS规范规定了如何定义一个模块, 如何暴露(导出)模块中的变量函数, 以及如何使用定义好的模块

-在CommonJS规范中一个文件就是一个模块
-在CommonJS规范中每个文件中的变量函数都是私有的,对其他文件不可见的
-在CommonJS规范中每个文件中的变量函数必须通过exports暴露(导出)之后其它文件才可以使用
-在CommonJS规范中想要使用其它文件暴露的变量函数必须通过require()导入模块才可以使用

1.什么是包? 前面说过在编写代码的时候尽量遵守单一原则, 也就是一个函数尽量只做一件事情 例如: 读取数据函数/写入数据函数/生成随机数函数等等, 不要一个函数既读取数据又写入数据又生成随机数, 这样代码非常容易出错, 也非常难以维护

在模块化开发中也一样, 在一个模块(一个文件中)尽量只完成一个特定的功能 但是有些比较复杂的功能可能需要由多个模块组成, 例如:
jQuery选择器相关的代码在A模块, CSS相关的代码在B模块, … 我们需要把这些模块组合在一起才是完成的jQuery 那么这个时候我们就需要一个东西来维护多个模块之间的关系 这个维护多个模块之间关系的东西就是"包"

简而言之: 一个模块是一个单独的文件, 一个包中可以有一个或多个模块

2.NodeJS包的管理 在NodeJS中为了方便开发人员发布、安装和管理包, NodeJS推出了一个包管理工具 NPM(Node Package Manager) NPM不需要我们单独安装, 只要搭建好NodeJS环境就已经自动安装好了
NPM就相当于电脑上的"QQ管家软件助手", 通过NPM我们可以快速找到我们需要的包, 可以快速安装我们需要的包,可以快速删除我们不想要的包等等

3.Node.js简单使用

  • 使用自己的数据
let num = 1;
console.log(num);

在这里插入图片描述

  • 导出数据,使用别人数据

1.在NodeJS中想要导出模块中的变量函数有三种方式
1.1通过exports.xxx = xxx导出
1.2通过module.exports.xxx = xxx导出
1.3通过global.xxx = xxx导出 注意点: 无论通过哪种方式导出, 使用时都需要先导入(require)才能使用 通过global.xxx方式导出不符合CommonJS规范, 不推荐使用
2.exports和module.exports区别
exports只能通过 exports.xxx方式导出数据, 不能直接赋值
module.exports既可以通过module.exports.xxx方式导出数据, 也可以直接赋值

注意点: 在企业开发中无论哪种方式都不要直接赋值, 这个问题只会在面试中出现

let num = 1;
//不赋值
exports.num = num;
module.exports.num = num;
赋值
exports = num; //{}
module.exports = num; //1
const aModule = require("./aDemo");
console.log(aModule);
console.log(aModule);

在这里插入图片描述

1.require注意点
1.1require导入模块时可以不添加导入模块的类型 如果没有指定导入模块的类型, 那么会依次查找.js .json .node文件 无论是三种类型中的哪一种, 导入之后都会转换成JS对象返回给我们

1.2导入自定义模块时必须指定路径 require可以导入"自定义模块(文件模块)"、“系统模块(核心模块)”、“第三方模块” 导入"自定义模块"模块时前面必须加上路径 导入"系统模块"和"第三方模块"是不用添加路径

1.3导入"系统模块"和"第三方模块"是不用添加路径的原因 如果是"系统模块"直接到环境变量配置的路径中查找 如果是"第三方模块"会按照module.paths数组中的路径依次查找

4.Node核心API

  • Buffer对象

0.准备知识
0.1计算机只能识别0和1(因为计算机只认识通电和断电两种状态),
0.2所有存储在计算机上的数据都是0和1组成的(数据越大0和1就越多)
0.3计算机中的度量单位
1 B(Byte字节) = 8 bit(位)
// 00000000 就是一个字节
// 111111111 也是一个字节
// 10101010 也是一个字节
// 任意8个 0或1的组合都是一个字节
1 KB = 1024 B
1 MB = 1024KB
1 GB = 1024MB

1.什么是Buffer?

Buffer是NodeJS全局对象上的一个类, 是一个专门用于存储字节数据的类 NodeJS提供了操作计算机底层的API,
而计算机底层只能识别0和1, 所以就提供了一个专门用于存储字节数据的类

2.如何创建一个Buffer对象

2.1创建一个指定大小的Buffer

Buffer.alloc(size[, fill[, encoding]])
let buf = Buffer.alloc(5);
console.log(buf);
// 注意点: 通过console.log();输出Buffer. 会自动将存储的内容转换成16进制再输出

在这里插入图片描述
2.2根据数组/字符串创建一个Buffer对象

Buffer.from(string[, encoding])
let buf1 = Buffer.alloc(5);
let buf2 = Buffer.alloc(5, 17);
console.log(buf1);
console.log(buf2);

//如果 fill 为 undefined,则 Buffer 将以零填充。
// 如果指定了 fill,则分配的 Buffer 将通过调用 buf.fill(fill) 进行初始化。

在这里插入图片描述
3.Buffer对象本质
本质就是一个数组

  • Buffer实例方法

1.将二进制数据转换成字符串
返回: 转换后的字符串数据。

buf.toString();
let buf = Buffer.from([97, 98, 99]);
console.log(buf);
console.log(buf.toString());

在这里插入图片描述
2.往Buffer中写入数据
string 要写入 buf 的字符串。
offset 开始写入 string 之前要跳过的字节数。默认值: 0。
length 要写入的字节数。默认值: buf.length - offset。
encoding string 的字符编码。默认值: ‘utf8’。
返回: 已写入的字节数。

buf.write(string[, offset[, length]][, encoding])
let buf = Buffer.alloc(5);
console.log(buf);

buf.write("abcdefg", 2, 2);
console.log(buf);
console.log(buf.toString());

在这里插入图片描述
3.从指定位置截取新Buffer
start 新 Buffer 开始的位置。默认值: 0。
end 新 Buffer 结束的位置(不包含)

buf.slice([start[, end]])
let buf1 = Buffer.from("abcdefg");
console.log(buf1);
let buf2 = buf1.slice(2,4);
console.log(buf2);
console.log(buf2.toString());

在这里插入图片描述

  • Buffer静态方法

1.检查是否支持某种编码格式

Buffer.isEncoding(encoding)
let res = Buffer.isEncoding("gbk");
console.log(res);

在这里插入图片描述
2.检查是否是Buffer类型对象

Buffer.isBuffer(obj)
let obj = Buffer.alloc(5);
let res = Buffer.isBuffer(obj);
console.log(res);

在这里插入图片描述
3.获取Buffer实际字节长度

Buffer.byteLength(string[, encoding])

注意点: 一个汉字占用三个字节

let buf1 = Buffer.from("123");
let buf2 = Buffer.from("知播渔");
let res1 = Buffer.byteLength(buf1);
let res2 = Buffer.byteLength(buf2);
console.log(res1);
console.log(res2);
console.log(buf1.length);
console.log(buf2.length);

在这里插入图片描述

4.合并Buffer中的数据

Buffer.concat(list[, totalLength])
let buf1 = Buffer.from("123");
let buf2 = Buffer.from("abc");
let buf3 = Buffer.from("xxx");
let res = Buffer.concat([buf1, buf2, buf3]);
console.log(res);
console.log(res.toString());

在这里插入图片描述

  • 路径Path

1.路径模块(path)

封装了各种路径相关的操作 和Buffer一样,NodeJS中的路径也是一个特殊的模块 不同的是Buffer模块已经添加到Global上了,
所以不需要手动导入 而Path模块没有添加到Global上, 所以使用时需要手动导入

2.获取路径的最后一部分

path.basename(path[, ext])
const path = require("path");
// basename用于获取路径的最后一个组成部分
let res1 = path.basename('/a/b/c/d/index.html');
let res2 = path.basename('/a/b/c/d');
let res3 = path.basename('/a/b/c/d/index.html', ".html");
console.log(res1);
console.log(res2);
console.log(res3);

在这里插入图片描述

3.获取路径

path.dirname(path)
const path = require("path");
// dirname用于获取路径中的目录, 也就是除了最后一个部分以外的内容
let res1 = path.dirname('/a/b/c/d/index.html');
let res2 = path.dirname('/a/b/c/d');
console.log(res1);
console.log(res2);

在这里插入图片描述

4.获取扩展名称

path.extname(path)
const path = require("path");
// extname用于获取路径中最后一个组成部分的扩展名
let res1 = path.extname('/a/b/c/d/index.html');
let res2 = path.extname('/a/b/c/d');
console.log(res1);
console.log(res2);

在这里插入图片描述

5.判断是否是绝对路径

path.isAbsolute(path)

注意点: 区分操作系统 在Linux操作系统中/开头就是绝对路径 在Windows操作系统中盘符开头就是绝对路径

在Linux操作系统中路径的分隔符是左斜杠 /
在Windows操作系统中路径的分隔符是右斜杠
在 Windows 上,正斜杠 (/) 和反斜杠 ( \ ) 都被接受作为路径片段分隔符;但是,path 方法只添加反斜杠 ( \ )。

const path = require("path");
let res1 = path.isAbsolute('/a/b/c/d/index.html'); // true
let res2 = path.isAbsolute('./a/b/c/d/index.html'); // false
let res3 = path.isAbsolute('c:\\a\\b\\c\\d\\index.html'); // true
let res4 = path.isAbsolute('a\\b\\c\\d\\index.html'); // false
console.log(res1);
console.log(res2);
console.log(res3);
console.log(res4);

在这里插入图片描述

6.获取当前操作系统(环境变量)分隔符

path.delimiter  //(windows是\ Linux是/)

如果是在Linux操作系统中运行那么获取到的是 :
如果是在Windows操作系统中运行那么获取到的是 ;

const path = require("path");
console.log(path.delimiter);

在这里插入图片描述

7.获取当前文件路径分隔符

path.sep  (windows中使用\\ linux中使用/)

如果是在Linux操作系统中运行那么获取到的是 左斜杠 /
如果是在Windows操作系统中运行那么获取到的是 右斜杠 \

const path = require("path");
console.log(path.sep);

在这里插入图片描述

1.路径的格式化处理

path.parse()  string->obj

path.format() obj->string
const path = require("path");
let obj = path.parse("/a/b/c/d/index.html");
console.log(obj);

在这里插入图片描述

const path = require("path");
let obj = {
    root: '/',
    dir: '/a/b/c/d',
    base: 'index.html',
    ext: '.html',
    name: 'index'
};
let str = path.format(obj);
console.log(str);

在这里插入图片描述

2.拼接路径

path.join([...paths])

注意点: 如果参数中没有添加/, 那么该方法会自动添加
如果参数中有…, 那么会自动根据前面的参数生成的路径, 去到上一级路径

const path = require("path");
let str1 = path.join("/a/b", "c");
let str2 = path.join("/a/b", "/c");
let str3 = path.join("/a/b", "/c", "../"); // /a/b/c --> /a/b
let str4 = path.join("/a/b", "/c", "../../"); // /a/b/c --> /a
console.log(str1);
console.log(str2);
console.log(str3);
console.log(str4);

在这里插入图片描述

3.规范化路径

path.normalize(path)
const path = require("path");
let res = path.normalize("/a//b///cd/index.html");
console.log(res);

在这里插入图片描述

4.计算相对路径

path.relative(from, to)
//用于将绝对路径转为相对路径,返回从 from 到 to 的相对路径(基于当前工作目录)。
const path = require("path");
let res = path.relative('/data/orandea/test/aaa', '/data/orandea/impl/bbb');
console.log(res);

在这里插入图片描述

5.解析路径

path.resolve([...paths])

注意点: 如果后面的参数是绝对路径, 那么前面的参数就会被忽略

const path = require("path");
let res1 = path.resolve('/foo/bar', './baz'); // /foo/bar/baz
let res2 = path.resolve('/foo/bar', '../baz'); // /foo/baz
let res3 = path.resolve('/foo/bar', '/baz'); // /baz
console.log(res1);
console.log(res2);
console.log(res3);

在这里插入图片描述

  • fs文件系统

封装了各种文件相关的操作
__dirname:当前目录路径
__filename:当前文件路径
console.log(__dirname); //D:\h5\2020webstorm\code\Node核心API
console.log(__filename); //D:\h5\2020webstorm\code\Node核心API\aDemo.js
方法名后缀有Sync表示是同步方法,没有Sync表示异步方法,需要通过回调函数获取数据

  1. 查看文件状态
fs.stat(path[, options], callback)
fs.statSync(path[, options])
const fs = require("fs");
console.log("1");
fs.stat(__dirname, function (err, stats) {
    // console.log(err);
    // birthtime: 文件的创建时间
    // mtime: 文件中内容发生变化, 文件的修改时间
    // console.log(stats);
    if(stats.isFile()){
        console.log("当前路径对应的是一个文件");
    }else if(stats.isDirectory()){
        console.log("当前路径对应的是一个文件夹");
    }
});
console.log("2");

在这里插入图片描述

const fs = require("fs");
let stats = fs.statSync(__filename);
console.log(stats);

在这里插入图片描述
2. 文件读取

fs.readFile(path[, options], callback)
fs.readFileSync(path[, options])

注意点: 没有指定第二个参数, 默认会将读取到的数据放到Buffer中 第二个参数指定为utf8, 返回的数据就是字符串

let fs = require("fs");
let path = require("path");
// 1.拿到需要读取的文件路径
//D:\h5\2020webstorm\code\Node核心API\data.txt
let str = path.join(__dirname, "data.txt");
console.log(str);
// 2.读取文件
/*
fs.readFile(str,"utf8", function (err, data) {
    if(err){
        throw new Error("读取文件失败");
    }
    console.log(data);
    // console.log(data.toString());
});
 */
let data = fs.readFileSync(str, "utf8");
console.log(data);

在这里插入图片描述

  1. 文件写入(覆盖源于的数据)
fs.writeFile(file, data[, options], callback)
fs.writeFileSync(file, data[, options])
let fs = require("fs");
let path = require("path");
// 1.拼接写入的路径
let str = path.join(__dirname, "lnj.txt");
// 2.写入数据
/*
// fs.writeFile(str, "知播渔 www.it666.com", "utf-8", function (err) {
 */
let buf = Buffer.from("www.itzb.com");
fs.writeFile(str, buf, "utf-8", function (err) {
    if(err){
        throw new Error("写入数据失败");
    }else{
        console.log("写入数据成功");
    }
});

// let res = fs.writeFileSync(str, "知播渔 www.it666.com", "utf-8");
// console.log(res);

在这里插入图片描述
在这里插入图片描述

  1. 追加写入(不会覆盖源于的数据)
fs.appendFile(path, data[, options], callback)
fs.appendFileSync(path, data[, options])
let fs = require("fs");
let path = require("path");
// 1.拼接写入的路径
let str = path.join(__dirname, "lnj.txt");
// 2.开始追加数据
fs.appendFile(str, "知播渔", "utf8", function (err) {
    if(err){
        throw new Error("追加数据失败");
    }else{
        console.log("追加数据成功");
    }
});
// fs.appendFileSync(str,"知播渔");
  1. 大文件操作
/*
// 1.生成读取和写入的路径
let readPath = path.join(__dirname, "test.mp4");
let writePath = path.join(__dirname, "abc.mp4");
// 2.创建一个读取流
let readStream = fs.createReadStream(readPath);
// 3.创建一个写入流
let writeStream = fs.createWriteStream(writePath);
// 4.监听读取流事件
readStream.on("open", function () {
    console.log("表示数据流和文件建立关系成功");
});
readStream.on("error", function () {
    console.log("表示数据流和文件建立关系失败");
});
readStream.on("data", function (data) {
    // console.log("表示通过读取流从文件中读取到了数据", data);
    writeStream.write(data);
});
readStream.on("close", function () {
    console.log("表示数据流断开了和文件的关系, 并且数据已经读取完毕了");
    writeStream.end();
});
// 5.监听写入流的事件
writeStream.on("open", function () {
    console.log("表示数据流和文件建立关系成功");
});
writeStream.on("error", function () {
    console.log("表示数据流和文件建立关系失败");
});
writeStream.on("close", function () {
    console.log("表示数据流断开了和文件的关系");
});
 */

// 1.生成读取和写入的路径
let readPath = path.join(__dirname, "test.mp4");
let writePath = path.join(__dirname, "abc.mp4");
// 2.创建一个读取流
let readStream = fs.createReadStream(readPath);
// 3.创建一个写入流
let writeStream = fs.createWriteStream(writePath);
// 利用读取流的管道方法来快速的实现文件拷贝
readStream.pipe(writeStream);

6.目录操作

  • 创建目录
fs.mkdir(path[, mode], callback)
fs.mkdirSync(path[, mode])
let fs = require("fs");
let path = require("path");

let str = path.join(__dirname, "abc");

fs.mkdir(str, function (err) {
    if(err){
        throw new Error("创建目录失败");
    }else{
        console.log("创建目录成功");
    }
});
  • 读取目录
fs.readdir(path[, options], callback)
fs.readdirSync(path[, options])
let fs = require("fs");
let path = require("path");

fs.readdir(__dirname, function (err, files) {
    if(err){
        throw new Error("读取目录失败");
    }else{
        console.log(files);
        files.forEach(function (obj) {
            // console.log(obj);
            let filePath = path.join(__dirname, obj);
            // console.log(filePath);
            let stats = fs.statSync(filePath);
            if(stats.isFile()){
                console.log("是一个文件", obj);
            }else if(stats.isDirectory()){
                console.log("是一个目录", obj);
            }
        });
    }
})

在这里插入图片描述

  • 删除目录
fs.rmdir(path, callback)
fs.rmdirSync(path)
let fs = require("fs");
let path = require("path");

let str = path.join(__dirname, "abc");
fs.rmdir(str, function (err) {
    if(err){
        throw new Error("删除目录失败");
    }else{
        console.log("删除目录成功");
    }
});
  • HTTP模块

通过Nodejs提供的http模块,我们可以快速的构建一个web服务器,
也就是快速实现过去PHP服务器的功能(接收浏览器请求、响应浏览器请求等)

通过HTTP模块实现服务器功能步骤:
1导入HTTP模块
2创建服务器实例对象
3绑定请求事件
4监听指定端口请求

  1. HTTP模块-搭建一个简单的web服务器
let http = require("http");
// 1.创建一个服务器实例对象
let server = http.createServer();
// 2.注册请求监听
server.on("request", function (req, res) {
    // end方法的作用: 结束本次请求并且返回数据
    // res.end("www.it666.com");
    // writeHead方法的作用: 告诉浏览器返回的数据是什么类型的, 返回的数据需要用什么字符集来解析
    res.writeHead(200, {
        "Content-Type": "text/plain; charset=utf-8"
    });
    res.end("知播渔");
});
// 3.指定监听的端口
server.listen(3000);

简写


http.createServer(function (req, res) {
    res.writeHead(200, {
        "Content-Type": "text/plain; charset=utf-8"
    });
    res.end("知播渔666"); }).listen(3000); ```

在这里插入图片描述

  1. HTTP模块-路径分发

1.什么是路径分发?
路径分发也称之为路由, 就是根据不同的请求路径返回不同的数据

2.如何根据不同的请求路径返回不同的数据?
通过请求监听方法中的request对象, 我们可以获取到当前请求的路径 通过判断请求路径的地址就可以实现不同的请求路径返回不同的数据

let http = require("http");

// 1.创建一个服务器实例对象
let server = http.createServer();
// 2.注册请求监听
/*
request对象其实是http.IncomingMessage 类的实例
response对象其实是http.ServerResponse 类的实例
* */
server.on("request", function (req, res) {
    res.writeHead(200, {
        "Content-Type": "text/plain; charset=utf-8"
    });
    // console.log(req.url);
    if(req.url.startsWith("/index")){
        // 注意点: 如果通过end方法来返回数据, 那么只会返回一次
        // res.end("首页1");
        // res.end("首页2");
        // 注意点: 如果通过write方法来返回数据, 那么可以返回多次
        //         write方法不具备结束本次请求的功能, 所以还需要手动的调用end方法来结束本次请求
        res.write("首页1");
        res.write("首页2");
        res.end();
    }else if(req.url.startsWith("/login")){
        res.end("登录");
    }else{
        res.end("没有数据");
    }
});
// 3.指定监听的端口
server.listen(3000);

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
3.HTTP模块-响应完整页面

拿到用户请求路径之后, 只需要利用fs模块将对应的网页返回即可

let http = require("http");
let path = require("path");
let fs = require("fs");

// 1.创建一个服务器实例对象
let server = http.createServer();
// 2.注册请求监听
server.on("request", function (req, res) {
    readFile(req, res);
});
// 3.指定监听的端口
server.listen(3000);

function readFile(req, res) {
    let filePath = path.join(__dirname, "www", req.url);
    fs.readFile(filePath, "utf8", function (err, content) {
        if(err){
            res.end("Server Error");
        }
        else {
            res.writeHead(200,{
                "Content-Type": "text/html; charset=utf-8"
            });
            res.end(content);
        }
    });
}

在这里插入图片描述
在这里插入图片描述
4.HTTP模块-响应静态资源

在给浏览器返回数据的时候, 如果没有指定响应头的信息, 如果没有设置返回数据的类型, 那么浏览器不一定能正确的解析

所以无论返回什么类型的静态资源都需要添加对应的响应头信息

let http = require("http");
let path = require("path");
let fs = require("fs");
let mime = require("./mime.json");
let ss = require("./15-StaticServer.js");

// 1.创建一个服务器实例对象
let server = http.createServer();
// 2.注册请求监听
server.on("request", function (req, res) {
    readFile(req, res);
});
// 3.指定监听的端口
server.listen(3000);

function readFile(req, res) {
    let filePath = path.join(__dirname, "www", req.url);
    // console.log(filePath);
    // 注意点:
    // 1.加载其它的资源(比如图片)不能写utf8
    // 2.如果服务器在响应数据的时候没有指定响应头, 那么在有的浏览器上, 响应的数据有可能无法显示
    let extName = path.extname(filePath);
    let type = mime[extName];
    console.log(type);
    console.log(typeof type);
    if(type.startsWith("text")){
        type += "; charset=utf-8;";
    }
    res.writeHead(200, {
        "Content-Type": type
    });
    fs.readFile(filePath, function (err, content) {
        if(err){
            res.end("Server Error");
        }
        res.end(content);
    });
}

5.区分GET-POST请求

在服务端如何区分用户发送的是GET请求和POST请求?
通过HTTP模块http.IncomingMessage 类的.method属性

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>18-HTTP模块-区分GET-POST请求</title>
</head>
<body>
<form action="http://127.0.0.1:3000/index.html" method="get">
    <input type="text" name="userName">
    <input type="text" name="password">
    <input type="submit" value="提交">
</form>
</body>
</html>
const http = require("http");

// 1.创建一个服务器实例对象
let server = http.createServer();
server.on("request", function (req, res) {
    // console.log(req.method);
    res.writeHead(200, {
        "Content-Type": "text/plain; charset=utf-8"
    });
    if(req.method.toLowerCase() === "get"){
        res.end("利用GET请求的方式处理参数");
    }else if(req.method.toLowerCase() === "post"){
        res.end("利用POST请求的方式处理参数");
    }
});
// 3.指定监听的端口
server.listen(3000);
  • URL模块-Get参数处理
url.format(urlObject)API接受一个对象或字符串并返回从该对象或字符串派生的格式化字符串。
url.parse(urlString[, parseQueryString[, slashesDenoteHost]])  一个URL字符串转换成对象并返回
//parseQueryString=true:将字符串转换成对象
let url = require("url");

let str = "http://root:123456@www.it666.com:80/index.html?name=lnj&age=68#banner";
console.log(url.parse(str));

在这里插入图片描述

const url = require("url");
const http = require("http");
// let str = "http://root:123456@www.it666.com:80/index.html?name=lnj&age=68#banner";
//console.log(url.parse(str,true));//parseQueryString=true 将字符串转换成对象

// 1.创建一个服务器实例对象
let server = http.createServer();
server.on("request", function (req, res) {
    // console.log(req.url);
    let obj = url.parse(req.url, true);
    res.end(obj.query.name + "----" + obj.query.age);
});
// 3.指定监听的端口
server.listen(3000);

在这里插入图片描述

  • querystring模块-POST参数处理

如何拿到POST请求传递过来的参数
使用querystring模块

querystring.parse(str[, sep[, eq[, options]]])  将参数转换为对象
querystring.stringify(obj[, sep[, eq[, options]]]) 将对象转换为参数
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>17-querystring模块-POST参数处理</title>
</head>
<body>
<form action="http://127.0.0.1:3000/index.html" method="post">
    <input type="text" name="userName">
    <input type="text" name="password">
    <input type="submit" value="提交">
</form>

</body>
</html>
const http = require("http");
const queryString = require("querystring");

// 1.创建一个服务器实例对象
let server = http.createServer();
server.on("request", function (req, res) {
    // 1.定义变量保存传递过来的参数
    let params = "";
    // 注意点: 在NODEJS中 ,POST请求的参数我们不能一次性拿到, 必须分批获取
    req.on("data", function (chunk) {
        // 每次只能拿到一部分数据
        params += chunk;
    });
    req.on("end", function () {
        // 这里才能拿到完整的数据
        // console.log(params);
        let obj = queryString.parse(params);
        // console.log(obj.userName);
        // console.log(obj.password);
        res.end(obj.userName + "----" + obj.password);
    });
});
// 3.指定监听的端口
server.listen(3000);

在这里插入图片描述
在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值