Nodejs基础之常用模块(三)

✍ 目录脑图

在这里插入图片描述

🔥Nodejs冲浪笔记地址
🔥Nodejs基础之JavaScript模块化(一)https://blog.csdn.net/Augenstern_QXL/article/details/119941988
🔥nodejs基础之包管理工具npm(二)https://blog.csdn.net/Augenstern_QXL/article/details/119990575
🔥Nodejs基础之常用模块(三)https://blog.csdn.net/Augenstern_QXL/article/details/119942024
🔥Nodejs基础之Express框架和art-template引擎(四)https://blog.csdn.net/Augenstern_QXL/article/details/119942262

✍Node是什么

  • Node 是一个基于 Chrome V8 引擎的 JavaScript 代码运行环境

  • 浏览器(软件)能够运行JavaScript代码,浏览器就是JavaScript代码的运行环境

  • Node(软件)能够运行JavaScript代码,Node就是JavaScript代码的运行环境

  • Node文档中文网:http://nodejs.cn/api/url.html#url_new_url_input_base

1、第一个Node程序

  1. 新建 app.js
  2. 输入代码块 node-http-server,自动生成 Node 结构(安装插件:Node-snippets就可以快捷生成

在这里插入图片描述

  1. 在终端使用 node app.js 运行程序

在这里插入图片描述

  1. 假如要停止我们的服务器,在终端处按 ctrl + c 停止服务器

1.1、解析第一个Node程序

  1. 引入 http 模块
var http = require("http");
  1. 创建服务器

    接下来我们使用 http.createServer() 方法创建服务器,并使用 listen 方法绑定 3000 端口。函数通过 request、response 参数来接收和响应数据

//表示引入http模块
var http = require('http');

/*
    request    获取客户端(浏览器)传过来的信息
    response   给浏览器响应信息
*/
http.createServer(function (request, response) {

  //发送响应头
  //设置HTTP头部,状态码是200,文件类型是 html,字符集是 utf8 
  response.writeHead(200, {'Content-Type': 'text/html;charset=UTF-8'});
    
  //表示给我们页面上面输出一句话并且结束响应
  response.end('Hello World');
}).listen(3000);  //监听端口

2、内置模块HTTP

Node.js中,将很多的功能,划分为一个个 module(模块)。 Node.js 中的很多功能都是通过模块实现。

//表示引入http模块
var http = require('http');

/*
    request    获取客户端(浏览器)传过来的信息
    response   给浏览器响应信息
*/
http.createServer(function (request, response) {

  //发送响应头
  //设置HTTP头部,状态码是200,文件类型是 html,字符集是 utf8 
  response.writeHead(200, {'Content-Type': 'text/html;charset=UTF-8'});
    
  //表示给我们页面上面输出一句话并且结束响应
  response.end('Hello World');
}).listen(3000);  //监听端口

在这里插入图片描述

那我们如果想在屏幕上输出汉字呢?

var http = require('http');

http.createServer(function(request, response) {

    //发送响应头
    response.writeHead(200, { 'Content-Type': 'text/html;charset=UTF-8' });

    //表示给我们页面上面输出一句话并且结束响应
    response.write('你好 Nodejs');
    response.end('<h2>你好 Nodejs</h2>');
}).listen(3000); //监听端口

在这里插入图片描述

如何解决 Preview 里面的乱码状态呢?只需要在http.createServer中添加下方代码即可

res.write("<head> <meta charset='UTF-8'></head>"); //解决乱码   

2.1、创建服务器

创建服务器对象,我们是通过 createServer 来完成的

  • req:request请求对象,包含请求相关的信息
  • res:response响应对象,包含我们要发送给客户端的信息

2.2、监听主机和端口号

通过listen方法来开启服务器,并且在某一个主机和端口上监听网络请求

listen函数有三个参数:

  • 端口port: 可以不传, 系统会默认分配端
  • 主机host: 通常可以传入localhost、ip地址127.0.0.1,或者ip地址0.0.0.0,默认是0.0.0.0
  • 回调函数:服务器启动成功时的回调函数
// 启动服务器,并且制定端口号和主机
server.listen(8888, '0.0.0.0', () => {
  console.log("服务器启动成功~");
});

2.3、request对象

在向服务器发送请求时,我们会携带很多信息,比如:

  • 本次请求的URL,服务器需要根据不同的URL进行不同的处理
  • 本次请求的请求方式,比如GET、POST请求传入的参数和处理的方式是不同的
  • 本次请求的 headers 中也会携带一些信息,比如客户端信息、接受数据的格式、支持的编码格式等

这些信息,Node会帮助我们封装到一个request的对象中,我们可以直接来处理这个request对象

const http = require('http');

// 创建一个web服务器
const server = http.createServer((req, res) => {
  // request对象中封装了客户端给我们服务器传递过来的所有信息
  console.log(req.url);
  console.log(req.method);
  console.log(req.headers);

  res.end("Hello Server");
});

// 启动服务器,并且制定端口号和主机
server.listen(8888, '0.0.0.0', () => {
  console.log("服务器启动成功~");
});

2.4、URL的处理

客户端在发送请求时,会请求不同的数据,那么会传入不同的请求地址:

  • 比如http://localhost:8000/login
  • 比如http://localhost:8000/products

服务器端需要根据不同的请求地址,作出不同的响应

// 创建一个web服务器
const server = http.createServer((req, res) => {

  //最基本的使用方式
  if (req.url === '/login') {
    res.end("欢迎回来~");
  } else if (req.url === '/users') {
    res.end("用户列表~");
  } else {
    res.end("错误请求, 检查~");
  }

那么如果用户发送的地址中还携带一些额外的参数呢?

比如:http://localhost:8000/login?name=why&password=123

这个时候,url的值是 /login?name=why&password=123

我们如何对它进行解析呢?使用内置模块url

3、url模块

3.1、旧版url API

我们来看一下 req 里面能够使用的东西。

  • 最重要的是 req.url 属性,表示用户的请求URL 地址。所有路由设计,都是通过 req.url 来实现的。
const http = require('http');

http.createServer(function(request, response) {

    console.log(request.url);


    //发送响应头
    response.writeHead(200, { 'Content-Type': 'text/html;charset="UTF-8"' });

    //表示给我们页面上面输出一句话并且结束响应
    response.write('你好 Nodejs');
    response.end('<h2>你好 Nodejs</h2>');
}).listen(3000); //监听端口

在这里插入图片描述

这里注意一下输出是在 Nodejs 控制台输出,而不是在浏览器上输出。因为输出是在服务端,浏览器是客户端

  • 我们比较关心的不是拿到 URL,而是识别这个 URL。
  • 识别 URL,下面的 url 模块

旧版本 Node 的 url 用法如下

url模块的使用说明
url.parse()解析 url(第二个参数为true,可以将 query 里面的数据转换为对象)
url.format(urlObject)是上面 url.parse() 操作的逆向操作
url.resolve(from,to)添加或者替换地址

在这里插入图片描述

const url = require('url');

var api = 'http://www.itying.com?name=zhangsan&age=20';

//console.log(url.parse(api, true));

var getValue = url.parse(api, true).query;

console.log(getValue);

// ES6中模板字符串写法
console.log(`姓名:${getValue.name}--年龄:${getValue.age}`);

在这里插入图片描述

3.2、新版url API

新版本 Node 的 url 用法如下

  • new URL(input,[,base])
    • input 类型:String,要解析的绝对或相对的输入网址。如果 input 是相对的,则需要 base。如果 input 是绝对的,则忽略 base。
const myURL = new URL('/foo', 'https://example.org/');
// https://example.org/foo
const url = require('url');

const myURL = new URL(
    "http://localhost:3000/p/a/t/h?name=zhangsan&age=20#hash");

console.log(myURL);

在这里插入图片描述

3.3、searchParams

searchParams 可以获取到 url 参数的 value

const myURL = new URL('https://example.org/?abc=123');
console.log(myURL.searchParams.get('abc'));
// 打印 123

myURL.searchParams.append('abc', 'xyz');
console.log(myURL.href);
// 打印 https://example.org/?abc=123&abc=xyz

myURL.searchParams.delete('abc');
myURL.searchParams.set('a', 'b');
console.log(myURL.href);
// 打印 https://example.org/?a=b

4、Nodejs工具

4.1、supervisor 工具

supervisor 会不停的watch 你应用下面的所有文件,发现有文件被修改,就重新载入程序文件这样就实现了部署,修改了程序文件后马上就能看到变更后的结果。麻麻再也不用担心我的重启nodejs 了

  1. 首先安装 supervisor(在cmd控制台输入下方代码)
npm install -g supervisor

在这里插入图片描述

  1. 使用 supervisor 代替 node 命令启动应用
supervisor app.js

4.2、nodemon

  • nodemon 和 supervisor 的功能一样,两者安装一个即可
  • 使用npm install -g nodemon 下载它(-g 是全局安装)
  • 在命令行工具中用nodemon命令替代node命令执行文件
nodemon app.js

5、内置模块fs

fs:file system ,文件操作系统,是系统模块,直接引入即可使用.

文件系统的API非常的多,我们不可能,也没必要一个个去学习,更多的是使用是时候去查对应的API

5.1、fs.stat🔥

fs.stat :检测是文件还是目录:

  • 第一个参数是 path :路径
  • 第二个参数是 callback:回调函数
const fs = require('fs');

// 1. fs.stat   检测是文件还是目录
fs.stat('./html',(err,data)=>{
    if(err){
        console.log(err);
        return;
    }

    console.log(`是文件:${data.isFile()}`);
    console.log(`是目录:${data.isDirectory()}`);

})

5.2、fs.mkdir🔥

fs.mkdir(): 创建目录

  • 第一个参数 path:将要创建的目录路径
  • 第二个参数 mode:目录权限(读写权限),默认为777
  • 第三个参数 callback:回调函数,传递异常参数 err
fs.mkdir('./css',(err)=>{

    if(err){
        console.log(err);
        return;
    }
    console.log('创建成功');
})

5.3、fs.writeFile🔥

fs.writeFile :创建写入文件

  • 第一个参数 filename:文件名称
  • 第二个参数 data:将要写入的内容,可以使用字符串或 buffer 数据
  • 第三个参数 options:option 数组对象,包含
    • encoding :可选值,默认为 ‘utf8’,当 data 使用 buffer 时,该值应该为 ignored
    • mode:文件读写权限,默认为 438
    • flag :默认为 ‘w’
  • 第四个参数 callback:回调函数,传递一个异常参数 err
fs.writeFile('./html/index.html','你好nodejs',(err)=>{
    if(err){
        console.log(err);
        return;
    }
    console.log('创建写入文件成功');
})

fs.writeFile('./html/index.html','你好nodejs 哈哈',(err)=>{
    if(err){
        console.log(err);
        return;
    }
    console.log('创建写入文件成功');
})

注意:如果没有这个文件,则会新建一个文件,如果已经有这个文件,那么会覆盖这个文件里面的内容

5.4、fs.appendFile

fs.appendFile 追加文件

  • 第一个参数 path:将要追加的文件路径
  • 第二个参数 data:要追加的文件内容
  • 第三个参数callback:回调函数,传递一个异常参数 err
fs.appendFile('./css/base.css','body{color:red}',(err)=>{
    if(err){
        console.log(err);
        return;
    }
    console.log('appendFile 成功');

})


 fs.appendFile('./css/base.css','h3{color:red}\n',(err)=>{

    if(err){
        console.log(err);
        return;
    }
    console.log('appendFile 成功');

})

注意:如果这个文件不存在,则会新建文件,如果文件已经存在,则会在文件内容后面追加内容

5.5、fs.readFile

fs.readFile 读取文件:

  • 第一个参数路径 path:想要读取的文件的路径
  • 第二个参数callback:回调函数,传递一个异常参数 err 和读取的文件数据 data,data类型是 Buffer
fs.readFile('./html/index.html',(err,data)=>{
    if(err){
        console.log(err);
        return;
    }
    console.log(data);
    console.log(data.toString());  //把Buffer 转化成string类型
})


fs.readFile('./aaa/index.html',(err,data)=>{
    if(err){
        console.log(err);
        return;
    }
    console.log(data);
    console.log(data.toString());  //把Buffer 转化成string类型
})

5.6、fs.readdir

fs.readdir 读取目录:

fs.readdir('./html',(err,data)=>{

    if(err){
        console.log(err);
        return;
    }

    console.log(data);
})

5.7、fs.rename

fs.rename :重命名,功能:1、表示重命名 2、移动文件

fs.rename('./css/aaa.css','./css/index.css',(err)=>{

    if(err){
        console.log(err);
        return;
    }

    console.log('重命名成功');

})


fs.rename('./css/index.css','./html/index.css',(err)=>{

    if(err){
        console.log(err);
        return;
    }
    console.log('移动文件成功');

})

5.8、fs.rmdir

fs.rmdir 删除目录

fs.rmdir('./aaaa',(err)=>{
    if(err){
        console.log(err);
        return;
    }
    console.log('删除目录成功');
})

注意:要删除目录之前需要先删除目录下的所有文件

5.9、fs.unlink

fs.unlink 删除文件

fs.unlink('./aaaa/index.html',(err)=>{
    if(err){
        console.log(err);
        return;
    }
    console.log('删除文件成功');
})

5.10、fs.createReadStream

fs.createReadStream: 从文件流中读取数据

const fs = require('fs');
// 以流的方式读取 data 目录下的 aaa.txt
var ReadStream = fs.createReadStream("./data/aaa.txt");


let count = 0;
var str = '';

// 通过 on 方法监听 data,表示我们读取到了这个数据
ReadStream.on('data', (data) => {
    str += data;
    count++;
})

// 通过 on 方法监听 end,表示我们读取完了这个数据
ReadStream.on('end', () => {
    console.log(str);
    console.log(count);
})

// 通过 on 方法监听 error,表示读取过程中的错误信息
ReadStream.on('error', (err) => {
    console.log(err);
})

5.11、fs.createWriteStream

fs.createWriteStream:写入文件

const fs = require('fs');


for(var i=0;i<500;i++){

    str +='我是从数据库获取的数据,我要保存起来'
}

// 以流的方式写到 data目录下的 output.txt
var writeStream = fs.createWriteStream('/data/output.txt');


writeStream.write(str); 

//标记写入完成
writeStream.end();
writeStream.on('finish',()=>{
    console.log('写入完成');
})

5.12、管道流🔥

管道提供了一个输出流到输入流的机制。通常我们用于从一个流中获取数据并将数据传递到另外一个流中。

在这里插入图片描述

const fs = require('fs');
// 创建一个可读流
var readerStream = fs.createReadStream('input.txt');
// 创建一个可写流
var readStream = fs.createReadStream('output.txt')
// 管道读写操作
// 读取 input.txt 文件内容,并将内容写入到 output.txt 文件中
readStream.pipi(writeStream);
console.log('程序执行完毕。');

6、同步与异步

6.1、同步API、异步API

  • 同步API可以从返回值中拿到API执行的结果, 但是异步API是不可以的
// 同步
function sum (n1, n2) { 
  return n1 + n2;
} 
const result = sum (10, 20);	// 30
// 异步
function getMsg () { 
  setTimeout(function () { 
      return { msg: 'Hello Node.js' }
  }, 2000);
  // return undefined;
}
const msg = getMsg (); // undefined
  • 同步API从上到下依次执行,前面代码会阻塞后面代码的执行
for (var i = 0; i < 100000; i++) { 
    console.log(i);
}
console.log('for循环后面的代码');
  • 异步API不会等待API执行完成后再向下执行代码
console.log('代码开始执行'); 
setTimeout(() => { console.log('2秒后执行的代码')}, 2000);
setTimeout(() => { console.log('"0秒"后执行的代码')}, 0); 
console.log('代码结束执行');
//代码开始执行
//代码结束执行
//"0秒"后执行的代码
//2秒后执行的代码

在这里插入图片描述

同步API 放在同步代码执行区,异步API放在异步代码执行区,同时将异步API 所对应的回调函数放在回调函数队列,这个时候注意,同步代码执行区和回调函数队列两者里面的代码没有执行,当同步代码区里面的内容执行完毕,这个时候去异步代码区,发现第二个 setTimeout 执行完毕,则将其对应的回调函数放入同步代码区执行,再去异步代码区发现第一个 setTimeout 执行完毕,再将其对应的回调函数放入同步代码区执行。

6.2、回调函数

自己定义函数让别人去调用。

回调函数视频讲解:https://www.bilibili.com/video/BV1UE411H71P?p=36

// getData函数定义
function getData (callback) {}
// getData函数调用
getData ( () => {});

getData 函数有一个形参 callback,传递的实参是一个函数,将一个函数作为另外一个函数的形参,则此形参就叫做回调函数。

function getData(callback) {
    callback('123');		// 使用callback可以调用下面的匿名函数function,并给callback传递参数
    //callback函数被调用了
}
// 调用函数
getData(function(n) {
    console.log('callback函数被调用了');
    console.log(n);			
    // 123
})
  • 我们可以调用 callback 回调函数将异步API执行的结果传递出来
function getMsg (callback) {
    // 调用callback将异步API执行的结果传递出来
    setTimeout(function () {
        callback ({ msg: 'Hello Node.js' })
    }, 2000);
}
getMsg (function (msg) { 
    console.log(msg);
    // { msg: 'Hello Node.js' }
});

6.3、Nodejs里面的异步API

fs.readFile('./demo.txt',(err,result) => {});
  • 读取文件是需要时间的,文件读取的结果不能通过返回值的方式获取,需要通过回调函数。
var server = http.createServer();
server.on('request',(req,res) => {});
  • 事件监测也是异步API

如果异步API后面代码的执行依赖当前异步API的执行结果,但实际上后续代码在执行的时候异步API还没有返回结果,这个问题要怎么解决呢?

例如,我们需要依次读取A文件、B文件、C文件

const fs = require('fs');

fs.readFile('./1.txt','utf8',(err,result1) => {
    console.log(result1);
    fs.readFile('./2.txt','utf8',(err,result2)=> {
        console.log(result2);
        fs.readFile('./3.txt','utf8',(err,result3)={
            console.log(result3);
        })
    })
})

回调嵌套的情况就叫做 回调地狱

6.4、Promise

Promise 出现的目的是解决 Node.js 异步编程中回调地狱的问题。

实际上,Promise 本身是一个构造函数,我们要解决回调地狱的问题,需要先使用 new 运算符创建 Promise 实例,在创建 Promise 实例的过程中,需要传入一个匿名函数,在匿名函数中有两个参数。

let promise = new Promise((resolve, reject) => {
    setTimeout(() => {
        if (true) {
            resolve({name: '张三'})
        }else {
            reject('失败了') 
        } 
    }, 2000);
});
promise.then(result => console.log(result) // {name: '张三'})
       .catch(error => console.log(error); // 失败了)

例如,我们需要依次读取A文件、B文件、C文件

function p1() {
    return  new Promise((resolve,reject) => {
    fs.readFile('./1.txt','utf8',(err,result) => {
        resolve(result);
    })
});
}

function p2() {
    return  new Promise((resolve,reject) => {
    fs.readFile('./2.txt','utf8',(err,result) => {
        resolve(result);
    })
});
}

function p3() {
    lreturn new Promise((resolve,reject) => {
    fs.readFile('./3.txt','utf8',(err,result) => {
        resolve(result);
    })
});
}

p1().then((r1) => {
    console.log(r1);
    return p2();         //返回一个promise对象
})
.then((r2) => {
    console.log(r2);
    return p3();
})
.then((r3) => {
    console.log(r3);
    return p3;
})

6.5、ES7异步函数

异步函数是异步编程语法的终极解决方案,它可以让我们将异步代码写成同步的形式,让代码不再有回调函数嵌套,使代码变得清晰明了。

const fn = async () => {};

async function fn () {}

6.5.1、async关键字

  • 普通函数定义前加async关键字 普通函数变成异步函数
  • 异步函数默认返回promise对象
  • 在异步函数内部使用return关键字进行结果返回 结果会被包裹在promise对象中 return关键字代替了resolve方法
  • 在异步函数内部使用throw关键字抛出程序异常
  • 调用异步函数再链式调用then方法获取异步函数执行结果
  • 调用异步函数再链式调用catch方法获取异步函数执行的错误信息
// 1. 普通函数定义前加async关键字,普通函数变成异步函数
// 2. 异步函数默认的返回值是promise 对象
async function fn() {
    throw '发生了一些错误';
    return 123;
}

fn ().then(function(data) {
    console.log(data); //123
}).catch(function (err) {
    console.log(err);    //发生了一些错误
})

6.5.2、await关键字

  • await关键字只能出现在异步函数中
  • await promise await后面只能写promise对象 写其他类型的API是不可以的
  • await关键字是暂停异步函数向下执行 直到promise返回结果
async function p1() {
    return 'p1';			// 返回的是 promise 对象
}
async function p2() {
    return 'p2';
}
async function p3() {
    return 'p3';
}
async function run() {
   await p1();
   await p2();
   await p3();
}
run();

简单理解:

  • async 是让方法变成异步
  • await 是等待异步方法执行完成

6.6、Node.js全局对象global

在浏览器中全局对象是 window,在 Node 中全局对象是 global。

Node 中全局对象有以下方法,可以在任何地方使用,global 可以省略

  • console.log() 在控制台输出、
  • setTimeout() 设置超时定时器
  • clearTimeout() 清除超时定时器
  • setInterval() 设置间歇定时器
  • clearInterval() 清除间歇定时器

注意:Node中不存在 BOM、DOM,所以全局对象是 global。但是在 DOM、BOM 中也有这些方法,只是全局对象是 window。

6.7、获取异步方法里面的数据

6.7.1、回调函数获取

// 回调函数 获取异步方法里面的数据
function getData(callbck){
    setTimeout(function(){
        var name='张三';
        callbck(name);
    },1000);
}

//外部获取异步方法里面的数据
getData(function(data){
 	console.log(data+'111');
})

6.7.2、Promise获取

//Promise来处理异步  resolve 成功的回调函数   reject失败的回调函数
var p=new Promise(function(resolve,reject){
 setTimeout(function(){
     var name='张三';
     if(Math.random()<0.7){
        resolve(name);
     }else{
        reject('失败');
     }
 },1000);
})

p.then((data)=>{
	console.log(data);
})

6.8、Async、Await使用

//普通方法
function test(){
    return '您好nodejs';
}

console.log(test());	// 您好nodejs


//异步方法
async function test(){   
    return '您好nodejs';
}

console.log(test());  //  Promise { '您好nodejs' }

async 是让方法变成异步,它返回的是 Promise,那我们要获取 Promise 对象里面的字符串要如何做呢?

//错误用法
async function test(){   //  Promise { '您好nodejs' }
    return '您好nodejs';
}

console.log(await test());  //错误  : await必须得用在async的方法里面


// 异步方法
async function test(){  
    return '您好nodejs';
}
// 正确获取异步方法里面的数据
async function main(){

    var data=await test();  //获取异步方法里面的数据

    console.log(data);
}
main();

我们当然最好是要返回的是 Promise 对象,否则也没必要将方法变为异步了。

// async 封装一个异步函数
async function test(){  
   return new Promise((resolve,reject)=>{
        setTimeout(function(){
            var name='张三 222';   
            resolve(name);
        },1000);
   })

}

async function main(){
    var data=await test();  //获取异步方法里面的数据
    console.log(data);
}
main();

7、内置模块Path

7.1、path常见的API

  • 从路径中获取信息
    • dirname:获取文件的父文件夹
    • basename:获取文件名
    • extname:获取文件扩展名
const path = require('path');


// 1.获取路径的信息
const filepath = '/User/why/abc.txt';

console.log(path.dirname(filepath)); // /User/why
console.log(path.basename(filepath)); // abc.txt
console.log(path.extname(filepath)); // .txt
  • 路径的拼接
    • 如果我们希望将多个路径进行拼接,但是不同的操作系统可能使用的是不同的分隔符
    • 这个时候我们可以使用 path.join 函数
// 2.join路径拼接
const basepath = '../User/why';
const filename = './abc.txt';
const othername = './why.js';

const filepath1 = path.join(basepath, filename);
console.log(filepath1);     // ..\User\why\abc.txt
  • 将文件和某个文件夹拼接
    • 如果我们希望将某个文件和文件夹拼接,可以使用path.resolve
    • resolve 函数会判断我们拼接的路径前面是否有 / 或 …/ 或 ./
    • 如果有表示是一个绝对路径,会返回对应的拼接路径
    • 如果没有,那么会和当前执行文件所在的文件夹进行路径的拼接
const path = require('path');

const basepath = '../User/why';
const filename = './abc.txt';
const othername = './why.js';
// 3.resolve路径拼接
// resolve会判断拼接的路径字符串中,是否有以/或./或../开头的路径
const filepath2 = path.resolve(basepath, filename, othername);
console.log(filepath2);
// E:\Code\Node\NodeCodeWhy\User\why\abc.txt\why.js
const path = require('path');


const basepath2 = '/User/coderwhy';
// const filename2 = '/why/abc.txt';              // E:\why\abc.txt
// const filename2 = './why/abc.txt';             // E:\User\coderwhy\why\abc.txt
// const filename2 = 'why/abc.txt';               // E:\User\coderwhy\why\abc.txt

// const filename2 = '../why/abc.txt';            // E:\User\why\abc.txt

const result = path.resolve(basepath2, filename2);
console.log(result);

7.1.1、path.extname

  • path.extname() 获取文件(可以是一个路径文件)的扩展名
const path = require('path');
console.log(path.extname('hello.md')); // md

// 获取路径信息的扩展名
let strPath = "http://www.xinhuanet.html";
console.log(path.extname(strPath)); // html

7.1.2、path.resolve

  • path.resolve([...paths]) 把一个路径或路径片段的序列解析为一个绝对路径
const path = require('path');

let arr = ['/sxt', 'qianduan', 'zhongji'];
let info1 = path.resolve(...arr);
console.log(info1);
// D:\sxt\qianduan\zhongji

给定的路径的序列是"从右往左"被处理的,后面每个 path 被依次解析,直到构造完成一个绝对路径。

7.1.3、path.join🔥

  • path.join([...paths]) 方法使用平台特定的分隔符把全部给定的 path 片段连接到一起,并规范化生成的路径。
path.join(__dirname,'./02art-template.js')


path.join('/foo','bar','./baz');
// 'foo/bar/baz'

path.join('/foo','bar','/baz','..');
// 'foo/bar'
  • __dirname 获得当前执行文件所在目录的完整目录名
  • __filename 获得当前执行文件的带有完整绝对路径的文件名

8、服务器端与客户端

网站应用程序主要分为两大部分:客户端和服务器端

  • 客户端:在浏览器中运行的部分,就是用户看到并与之交互的界面程序。使用HTML、CSS、JS构建
  • 服务器端:在服务器中运行的部分,负责存储数据和处理应用逻辑。(可以将服务器端理解为另一台电脑)

9、路由

路由指的就是针对不同请求的URL,处理不同的业务逻辑。

在这里插入图片描述

const http = require('http');
const url = require('url');

http.createServer(function(request, response) {
    response.writeHead(200, { 'Content-Type': 'text/html;charset=UTF-8' });
    // 解构写法,相当于 request.url
    const { url } = request;
    if (url == '/' || url == 'index') {
        response.end('欢迎来到首页');
    } else if (url == '/list') {
        response.end('欢迎来到列表页');
    } else {
        response.end('抱歉,您访问的页面出游了~');
    }

    response.end('Hello World');
}).listen(3000);

console.log('Server running at http://127.0.0.1:3000/');

在这里插入图片描述

9.1、Get请求

在客户端和服务器之间进行请求 - 响应时,两种最常被用到的方法是:GET 和 POST

  • GET - 从指定的资源请求数据。(一般用于获取数据)
    • request.url 获取请求地址
    • request.method 获取请求方法
  • POST - 向指定的资源提交要被处理的数据。(一般用于提交数据)
http.createServer(function(request, response) {

    //发送响应头
    //设置HTTP头部,状态码是200,文件类型是 html,字符集是 utf8 
    response.writeHead(200, { 'Content-Type': 'text/html;charset=UTF-8' });
    
    console.log(request.url); // 获取请求地址		/index.html
    console.log(request.method); // 获取请求方法	GET/POST
    
    //表示给我们页面上面输出一句话并且结束响应
    response.end('Hello World');
}).listen(3000); //监听端口

9.1.1、GET请求参数

  • 参数被放置在浏览器地址栏中,例如:http://localhost:3000/?name=zhangsan&age=20

  • 参数获取需要借助系统模块url,url模块用来处理url地址

    • request.url 获取 /name=zhangsan&age=20

    • request.headers.host 获取 127.0.0.1:3000

    • const myURL = new URL(url, `http://{host}`);
      
    • 如上获取到 url 对象,再从对象中获取参数

在这里插入图片描述

const http = require('http');
const url = require('url');

http.createServer(function(request, response) {
    response.writeHead(200, { 'Content-Type': 'text/html;charset=UTF-8' });
    // 解构写法,相当于 request.url
    const { url } = request;
    // 解构写法,相当于 request.headers.host
    const { host } = request.headers;

    if (url !== '/favicion.ico') {
        const myURL = new URL(url, `http://{host}`);
        response.write(`name: ${myURL.searchParams.get("name")},age: ${myURL.searchParams.get("age")}`);

    }
    response.end('Hello World');
}).listen(3000);

console.log('Server running at http://127.0.0.1:3000/');

在这里插入图片描述

9.2、Post请求

  • 参数被放置在请求体中进行传输
  • 获取 POST 参数需要使用 data 事件和 end 事件
  • 使用 querystring 系统模块将参数转化为对象格式
const http = require('http');
// 处理请求参数模块
const queryString = require('querystring');

http.createServer(function (request, response) {
  response.writeHead(200, {'Content-Type': 'text/plain'});
  // data 当请求参数传递的时候触发data事件
  // end 当请求参数传递完成的时候触发end事件
  let postParams = '';
  request.on('data',(params)=>{
    postParams += params;
  })
  request.on('end',()=>{
    console.log(postParams);            // 接收到的是一个字符串
    console.log(queryString.parse(postParams));        // 使用queryString将字符串转化为对象    
  
})
  response.end('Hello World');


}).listen(3000);
  • 10
    点赞
  • 24
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 7
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

生命是有光的

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值