likes
comments
collection
share

速通NodeJS基础知识——http/url/fs等内置模块

作者站长头像
站长
· 阅读数 12

速通NodeJS基础知识——http/url/fs等内置模块 本文旨在结合代码案例总结了NodeJS常见内置模块的使用,包括:模块规范、url、querystring、http、event、fs、zlib以及crypto库

一、模块规范

CommonJSESModule都是用于在JavaScript中组织和导入/导出代码的规范,它们的主要区别在于实现和用途。

1-CommonJS

CommonJS是使用require()函数来加载依赖模块,使用module.exports对象来导出模块,具有以下特点:

  • 同步加载模块
  • 运行时加载
  • 导出是复制一个值的引用
// 导出模块
module.exports = {  
  foo: 'hello',  
  bar: () => console.log('world')  
};  
// 导入模块
const module = require('./module');  
module.bar; // world

2-ESModule

使用import语句来导入模块,使用export语句来导出模块; 在导入export时,需要通过大括号{}指定所需变量名称; 而在导入export default时,则不需要使用大括号。具有以下特点:

  • 异步加载模块,可以并行加载多个模块
  • 编译时加载,可以进行静态分析和优化。
  • 导出是一种动态连接,可以实现更灵活的代码组织和依赖管理。
// 导出模块
export const foo = 'hello';  
export function bar() {  
  console.log('world');  
}  
export default () => console.log('default');  
  
// 导入模块  
import { foo, bar } from './module';  
import defaultFunc from './module';  
  
console.log(foo); // 'hello' 
bar(); // 'world'
defaultFunc(); // 'default'

二、url

url库可以用于处理和解析 URL

const url = require('url');

1、parse

将 URL 字符串解析为 URL 对象

url.parse(urlString[, parseQueryString[, slashesDenoteHost]])

其中,urlString是要解析的URL字符串,parseQueryString指定是否要将查询参数解析为一个对象,默认为falseslashesDenoteHost指定如果没有提供协议,是否将双斜杠视为主机名的一部分,默认为false

2、format

url.format(urlObject): 将 URL 对象转换为 URL 字符串。

3、resolve

url.resolve(from, to): 从基础 URL 和相对 URL 中计算出目标 URL。

4、URL

这是一个全局类,在 Node.js v10.0.0 版本中引入

new URL(input[, base]): 创建一个新的 URL 对象。

虽然 URL 是一个全局类,但在编写 Node.js 应用程序时,最好还是显式地导入 URL 类,以便代码更加清晰和易于维护。

const { URL } = require('url');

三、querystring

querystring库可以用于处理和解析 URL中的query参数

var str = "name=zhangsan&age=10&height=170";

var querystring = require("querystring");

var obj = querystring.parse(str);

1、parse

querystring.parse(str[, sep[, eq[, options]]]): 将 URL 查询字符串解析为 JavaScript 对象。参数 sep 和 eq 分别指定分隔符和赋值符号,默认值为 & 和 =。。

2、stringify

querystring.stringify(obj[, sep[, eq[, options]]]): 将 JavaScript 对象序列化为 URL 查询字符串。参数 sep 和 eq 分别指定分隔符和赋值符号,默认值为 & 和 =。

3、escape

querystring.escape(str): 对给定的字符串进行 URL 编码,使其在 URL 查询字符串中能够安全使用。

4、unescape

querystring.unescape(str): 对已编码的字符串进行解码。

四、http

1、server

创建服务器

const http = require("http");  
const server = http.createServer();  
server.on("request", (req, res) => {
  // req 接受浏览器传的参数
  // res 返回渲染内容
});
server.listen(3000, () => {
  console.log("server start!");
});

2、jsonp

JSONP(JSON with Padding)是一种跨域通信的解决方案,它利用了 HTML 中 script 标签可以跨域加载数据的特性来实现。在使用 JSONP 方案时,服务器端需要将数据包装成一个 JavaScript 函数返回给客户端调用。

下面是一个简单的案例

浏览器端

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>jsonp</title>
</head>
<body>
  <script>
    var oscript = document.createElement('script')
    oscript.src = 'http://localhost:3000?callback=stars'
    document.body.appendChild(oscript)
    function stars(obj) {
      console.log(obj);
    }
  </script>
</body>
</html>

node服务端

var http = require("http");
var url = require("url");
http
  .createServer((req, res) => {
    const myUrl = url.parse(req.url, true);
    res.end(
      `${myUrl.query.callback}(${JSON.stringify({
        name: "stars",
        age: 20,
      })})`
    );
  })
  .listen(3000, () => {
    console.log("server star");
  });

3、CORS

CORS(Cross-Origin Resource Sharing)是一种跨域资源共享的解决方案,可以让浏览器在安全的前提下,实现从一个源站点向另一个站点发起跨域请求。CORS 的原理基于以下几个步骤:

  • 客户端发送跨域请求时,会在请求头中加入 Origin 字段,该字段表示当前页面的源地址。
  • 服务端接收到请求后,根据 Origin 字段判断请求是否来自合法的源站点。
  • 如果请求来自合法的源站点,则服务端需要在响应头中添加 Access-Control-Allow-Origin 字段,并将其值设置为客户端请求中的源地址或 *。这样客户端就能够通过检查响应头信息,判断该请求是否被允许。
  • 此外,服务端还可以在响应头中添加其他的 CORS 头信息,如 Access-Control-Allow-Methods、Access-Control-Allow-Headers 等,以指定允许的请求方法、请求头信息等内容。

浏览器端

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>cors</title>
</head>
<body>
  <script>
    fetch("http://localhost:3000/api/aaa").then(res => res.json()).then(res => {
      console.log(res);
    })
  </script>
</body>
</html>

服务器端

var http = require("http");
var url = require("url");
http
  .createServer((req, res) => {
    const myUrl = url.parse(req.url, true);
    res.writeHead(200, {
      "Content-Type": "application/json;charset=utf-8",
      // cors头
      "access-control-allow-origin": "*",
    });
    switch (myUrl.pathname) {
      case "/api/aaa":
        res.end(
          `${JSON.stringify({
            name: "stars",
            age: 20,
          })}`
        );
        break;
      default:
        res.end("404");
    }
  })
  .listen(3000);

4、get

直接上案例

发起请求

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>get请求</title>
</head>
<body>
  <script>
    fetch("http://localhost:3000/api/aaa").then(res => res.json()).then(res => {
      console.log(res);
    })
  </script>
</body>
</html>

响应请求

var http = require("http");
var https = require("https");
var url = require("url");
http
  .createServer((req, res) => {
    const myUrl = url.parse(req.url, true);
    res.writeHead(200, {
      "Content-Type": "application/json;charset=utf-8",
      // cors头
      "access-control-allow-origin": "*",
    });
    switch (myUrl.pathname) {
      case "/api/aaa":
        httpGet((data) => {
          res.end(data);
        });
        break;
      default:
        res.end("404");
    }
  })
  .listen(3000);
function httpGet(callback) {
  var data = "";
  https.get(
    "https://i.maoyan.com/api/mmdb/movie/v3/list/hot.json?ct=%E6%B7%B1%E5%9C%B3&ci=30&channelId=4",
    (res) => {
      res.on("data", (chunk) => {
        data += chunk;
      });
      res.on("end", () => {
        callback(data);
      });
    }
  );
}

5、post

直接上案例

发起请求

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>post请求</title>
</head>
<body>
  <script>
    fetch("http://localhost:3000/api/aaa").then(res => res.json()).then(res => {
      console.log(res);
    })
  </script>
</body>
</html>

响应请求

var http = require("http")
var https = require("https");
var url = require("url");
http
  .createServer((req, res) => {
    const myUrl = url.parse(req.url, true);
    res.writeHead(200, {
      "Content-Type": "application/json;charset=utf-8",
      // cors头
      "access-control-allow-origin": "*",
    });
    switch (myUrl.pathname) {
      case "/api/aaa":
        httpPost((data) => {
          res.end(data);
        });
        break;
      default:
        res.end("404");
    }
  })
  .listen(3000);
function httpPost(callback) {
  var data = "";
  var options = {
    hostname: "m.xiaomiyoupin.com",
    post: "443",
    path: "/mtop/market/search/placeHolder",
    method: "post",
    headers: {
      "Content-Type": "application/json",
    },
  };
  var req = https.request(options, (res) => {
    res.on("data", (chunk) => {
      data += chunk;
    });
    res.on("end", () => {
      callback(data);
    });
  });
  req.write(JSON.stringify([{}, { baseParam: { ypClient: 1 } }]));
  req.end();
}

五、event

在 Node.js 中,事件(Event)是一种基本的异步编程模型,通过触发事件和监听事件来实现不同模块之间的通信

const EventEmitter = require("events");
const event = new EventEmitter();
event.on("play", (arg1, arg2) => {
  console.log("事件触发了", arg1, arg2);
});
event.emit("play", "arg1", "arg2");

六、fs

在 Node.js 中,fs(File System)模块提供了对文件和目录进行读写操作的 API。使用 fs 模块可以轻松地进行文件操作,例如创建文件、删除文件、读取文件内容、写入文件内容等。

// 新建文件夹
fs.mkdir("./file", (err) => {
  if (err && err.code === "EEXIST") {
    console.log("文件已存在,创建文件失败");
  }
});

// 重命名文件
fs.rename("./file3", "./file2", (err) => {
  if (err && err.code === "ENOENT") {
    console.log("目录不存在,重命名文件失败");
  }
});

// 删除文件夹,需要保证目录为空
fs.rmdir("./file2", (err) => {
  if (err && err.code === "ENOENT") {
    console.log("目录不存在,删除文件失败");
  }
});

// writeFile,写文件,若存在,直接覆盖
fs.writeFile("./file/test.txt", "hello world", (err) => {
  console.log("writeFile", err);
});

// appendFile,追加文件内容,若不存在,新建文件
fs.appendFile("./file/test2.txt", "test", (err) => {
  console.log("appendFile", err);
});

// readFile,读取文件内容
fs.readFile("./file/test.txt", "utf-8", (err, data) => {
  if (!err) {
    console.log("readFile", data);
  }
});

// unlink,删除文件内容
fs.unlink("./file/detele.txt", (err) => {
  console.log("unlink", err);
});

// readdir,读取目录结构
fs.readdir("./file", (err, data) => {
  if (!err) {
    console.log("readdir", data);
  }
});

// stat,判断是文件还是文件夹
fs.stat("./file", (err, data) => {
  if (!err) {
    console.log("stat1", data.isDirectory());
    console.log("stat2", data.isFile());
  }
});

// 可读流
const fs = require("fs");
const read = fs.createReadStream("./file/test.txt", "utf-8");
read.on("data", (chunk) => {
  console.log("---", chunk);
});
read.on("end", () => {
  console.log("end");
});
read.on("error", (err) => {
  console.log("err", err);
});
const write = fs.createWriteStream("./file/test1.txt", "utf-8");
write.write("hello world");
write.write("你好");
write.end();
const write2 = fs.createWriteStream("./file/test2.txt", "utf-8");
read.pipe(write2);

七、zlib

使用 zlib 模块,可以轻松地进行数据压缩和解压缩操作

const http = require("http");
const fs = require("fs");
const zlib = require("zlib");
const gzip = zlib.createGzip();
http
  .createServer((req, res) => {
    const readStream = fs.createReadStream("./test.txt");
    res.writeHead(200, {
      "Content-Type": "application/x-javascript;charset=utf-8",
      "Content-Encoding": "gzip",
    });
    readStream.pipe(gzip).pipe(res);
  })
  .listen(3000, () => {
    console.log("server start");
  });

压缩前 速通NodeJS基础知识——http/url/fs等内置模块 压缩后 速通NodeJS基础知识——http/url/fs等内置模块

八、crypto

crypto 模块提供了加密、解密、签名、验证等各种安全相关的功能

const crypto = require("crypto");
// 哈希计算
const hash = crypto.createHash("md5");
hash.update("123456");
console.log(hash.digest("hex"));
// 增强
const hashPlus = crypto.createHmac("md5", "secret-key");
hashPlus.update("123456");
console.log(hashPlus.digest("hex"));
// 对称加密
function encrypto(key, iv, data) {
  let dep = crypto.createCipheriv("aes-128-cbc", key, iv);
  return dep.update(data, "binary", "hex") + dep.final("hex");
}
function decrypto(key, iv, data) {
  let cryptoed = Buffer.from(data, "hex").toString("binary");
  let dep = crypto.createDecipheriv("aes-128-cbc", key, iv);
  return dep.update(cryptoed, "binary", "utf8") + dep.final("utf8");
}
const encryptoed = encrypto("1122334455667788", "aabbccddeeffgghh", "stars");
console.log("加密", encryptoed);
console.log(
  "解密",
  decrypto("1122334455667788", "aabbccddeeffgghh", encryptoed)
);