node.js从入门到快速开发一个简易的web服务器

浏览器中JavaScript学习路径:

JavaScript基础语法+浏览器内置API(DOM+BOM)+第三方库(jQuery,art-template等)

Node.js的学习路径

JavaScript基础语法+Node.js内置API模块(fs、path、http等)+第三方API模块(express、mysql等)

Node.js安装

通过Node.js 来运行Javascript 代码,则必须在计算机上安装Node.js 环境

安装包可从Node.js 的官网首页下载,进入到 Nodejs 的官网首页(cc),点击绿色的按钮,下载所需的版本后,双击直接安装即可。

区分 LTS 版本和 Current 版本的不同

  • LTS 为长期稳定版,对于追求稳定性的企业级项目来说,推荐安装 LTS 版本的 Node.js。
  • @Current 为新特性尝鲜版,对热衷于尝试新特性的用户来说,推荐安装 Current 版本的 Node.js。但是,Current 版本中可
    能存在隐的Bug 或安全性漏洞,因此不推荐在企业级项目中使用 Current 版本的 Node.js。

查看已安装的 Nodejs 的版本号

  • window+r打开终端,在终端输入命令 node -v 后,按下回车键,即可查看已安装的 Node.js 的版本号

在 Node.js 环境中执行 JavaScript 代码

  • 准备一个js文件

    js 复制代码
    console.log('hello node.js')
  • 打开终端,输入 node 要执行的js文件的路径

什么是fs文件系统模块

fs 模块是 Node.js 官方提供的、用来操作文件的模块。它提供了一系列的方法和属性,用来满足用户对文件的操作需求.

  • fs.readFile() 方法,用来读取指定文件中的内容
  • fs.writeFile() 方法,用来向指定的文件中写入内容

如果要在 JavaScript代码中,使用fs 模块来操作文件,则需要先导入这个模块:

javascript 复制代码
const fs = require('fs');

使用一个fs常量接收这个fs,我们接收了这个fs,后面就可以调用fs里面的方法

读取指定文件中的内容

fs.readFile()的语法格式

使用fs.readFile()方法,可以读取指定文件中的内容,语法格式如下:

js 复制代码
fs.readFile(path[,options],callback)

参数optins解读

  • 参数1:必选参数,字符串,表示文件的路径
  • 参数2:可选参数,表示以什么编码格式来读取文件。
  • 参数3:必选参数,文件读取完成后,通过回调函数拿到读取的结果。
  • 参数4:必选参数,文件写入完成后的回调函数

示例

fs.readFile()的示例代码

以utf8的编码格式,读取指定文件的内容,并打印err和dataStr的值

javascript 复制代码
//导入fs模块,来操作文件
const fs = require('fs')

//调用fs.readFile()方法读取文件
//参数1:读取文件的存放路径
//参数2:读取文件时候采用的编码格式,一般默认指定utf8
//参数3:回调函数,拿到读取失败和成功的结果 err,dataStr
fs.readFile('./files/hello.txt', 'utf8',
    function(err, dataStr) {
        //打印失败的结果
        console.log(err)
        console.log('----')
            //打印成功的结果
        console.log(dataStr)
    })
3判断文件是否读取成功
可以判断err 对象是否为 null,从而知晓文件读取的结果

判断文件是否读取成功

可以判断err 对象是否为 null,从而知晓文件读取的结果

javascript 复制代码
//导入fs模块,来操作文件
const fs = require('fs')

//调用fs.readFile()方法读取文件
//参数1:读取文件的存放路径
//参数2:读取文件时候采用的编码格式,一般默认指定utf8
//参数3:回调函数,拿到读取失败和成功的结果 err,dataStr
fs.readFile('./files/hello.txt', 'utf8',
    function(err, dataStr) {
        //打印失败的结果,err为null回自动转为布尔值
        if (err) {
            return console.log('文件读取失败', err.message)
        } else {
            //打印成功的结果
            console.log(dataStr)
        }

    })

案例:整理用户信息数据

user.txt

小明 年龄=20;小红 年龄=18;小黑 年龄=17
javascript 复制代码
const fs = require('fs')

fs.readFile('./files/user.txt', 'utf8', function(err, dataStr) {
    if (err) {
        return console.log('读取文件失败!' + err.message);
    }

    //先把成绩的数据,按照;进行分隔
    const arrOld = dataStr.split(';')
        //分隔之后对字符串进行替换操作
    for (index = 0; index < arrOld.length; index++) {
        const element = arrOld[index];
        arrOld[index] = '姓名:' + element.replace('=', ':')
    };

    const newStr = arrOld.join('\r\n')
    console.log(newStr)

    fs.writeFile('./files/user-new.txt', newStr, function(err) {
        if (err) {
            return console.log('写入文件失败!' + err.message)
        }
        console.log('写入成绩成功')
    });
});
javascript 复制代码
const fs = require('fs')

fs.readFile('./files/user.txt', 'utf8', function(err, dataStr) {
    if (err) {
        return console.log('读取文件失败!' + err.message);
    }

    //先把成绩的数据,按照;进行分隔
    const arrOld = dataStr.split(';')
        //分隔之后对字符串进行替换操作
    const arrNew = []
    arrOld.forEach(item => {
        arrNew.push('姓名:' + item.replace('=', ':'))
    });

    const newStr = arrNew.join('\r\n')
    console.log(newStr)

    fs.writeFile('./files/user-new.txt', newStr, function(err) {
        if (err) {
            return console.log('写入文件失败!' + err.message)
        }
        console.log('写入成绩成功')
    });
});

fs路径动态拼接问题:

如果提供的操作路径是以./或./开头的相对路径时,很容易出现路径动态接错误的问题在使用 fs模块操作文件时。

  • 原因:代码在运行的时候会以执行 node 命令时所处的目录,动态拼接出被操作文件的完整路径。
  • 解决:使用完整路径,缺点移植性查差

fs路径问题-使用__dirname(注意是双下划线)完美解决路径的动态拼接问题

javascript 复制代码
fs.readFile(__dirname+'/files/hello.txt', 'utf8',
    function(err, dataStr) {
        //打印失败的结果
        if (err) {
            return console.log('文件读取失败', err.message)
        } else {
            //打印成功的结果
            console.log(dataStr)
        }

    })

注意点:

  • fs.writeFile() 方法只能用来创建文件,不能用来创建路径
  • 重复调用fs.writeFile()写入同一个文件,新写入的内容会覆盖之前的旧内容

什么是path路径模块?

path 模块是 Node.js 官方提供的、用来处理路径的模块。它提供了一系列的方法和属性,用来满足用户对路径的处理需求。

例如:

  • path.join0 方法,用来将多个路径片段拼接成一个完整的路径字符串
  • path.basename0 方法,用来从路径字符串中,将文件名解析出来

如果要在JavaScript代码中,使用 path 模块来处理路径,则需要使用如下的方式先导入它

const path = require('path')

path.join()的语法格式

使用路径path.Join()方法,可以把多个路径片段拼接为完整的路径字符串,语法格式如下:

path.join([...paths])

参数解读:

  • ...paths <string>路径片段的序列
  • 返回值:<string>

path.join()的代码示例

使用path.join()方法,可以把多个路径片段拼接为完整的路径字符串

javascript 复制代码
const pathStr = path.join( '/a',"/b/c','../','./d','e')
console.log(pathstr) // 输出 a\b\d\e
const pathStr2 = path.join(__dirname,'./files/1.txt')
console.log(pathstr2) // 输出 当前文件所处目录\files\1.txt

注意:凡是涉及到路径拼接的操作,都要推荐使用 path.join0 方法进行处理。不要直接使用 + 进行字符串的拼接。

javascript 复制代码
const path = require('path')
const fs = require('fs')
    // 注意: 在path.join../ 会抵消前面的路径
fs.readFile(path.join(__dirname, '/files/user.txt'), 'utf8', function(err, Str) {
    if (err) {
        return console.log(err.message)
    }
    console.log(Str)
})

path.basename()的语法格式

使用 path.basename0 方法,可以获取路径中的最后一部分,经常通过这个方法获取路径中的文件名,语法格式如下:

path.basename(path[,ext])

参数解读:

  • path <string>必选参数,表示一个路径的字符串
  • ext <string>可选参数,表示文件扩展名
  • 返回 <string>表示路径中的一部分

path.basename()的代码示例

使用 path.basename()方法,可以从一个文件路径中,获取到文件的名称部分:

javascript 复制代码
 const fpath ='/a/b/c/index.html' // 文件的存放路径
 var fullName = path.basename(fpath)
 console.log(fullName) // 输出 index.html

 var nameWithoutExt = path.basename(fpath,html')
 console.log(nameWithoutExt) //输出index

path.extname()的语法格式

使用path.extname()方法,可以获取路径中的扩展名部分,语法格式如下:

  • 表示一个路径的字符串
  • 返回: <string>返回得到的扩展名字符串
javascript 复制代码
const fpath = '/a/b/c/index.html' //路径字符串
const fext = path.extname(fpath)
console.log(fext) //输出.html

什么是http模块?

什么是客户端、什么是服务器?

在网络节点中,负责消费资源的电脑,叫做客户端;负责对外提供网络资源的电脑,叫做服务器。

http 模块是 Node.js 官方提供的、用来创建 web 服务器的模块。通过 http 模块提供的 http.createServer()方法,就能方便的把一台普通的电脑,变成一台Web 服务器,从而对外提供 Web 资源服务

使用http模块创建Web服务器,需要导入:

javascript 复制代码
const http = require('http')

服务器和普通电脑的区别在于,服务器上安装了 web 服务器软件,例如:IIS(asp)、Apache(php) 、tomcat(jsp)等。通过安装这些服务器软件就能把一台普通的电脑变成一台web 服务器

在 Node.js 中,不需要使用 IS、Apache 等这些第三方 web 服务器软件。因为我们可以基于 Node,js 提供的http 模块,通过几行简单的代码,就能轻松的手写一个服务器软件,从而对外提供 web 服务。

创建最基本的web服务器

1.创建 web 服务器的基本步骤

  • 导入http 模块

    javascript 复制代码
    const http = require('http')
  • 创建web 服务器实例

    调用 http.createServer0 方法,即可快速创建一个 web 服务器实例:

    javascript 复制代码
    const server = http.createServer()
  • 为服务器实例绑定 request 事件,监听客户端的请求

    为服务器实例绑定request 事件,即可监听客户端发送过来的网络请求

    //使用服务器实例的 .on()方法,为服务器绑定一个request事件
    server.on('request',(req,res)=>{
    	//只要有客户端来请求我们自己的服务器,就会触发request事件,从而调用这个事件处理函数
    	console.log('request coming')
    })
    
  • 启动服务器

    调用服务器实例的.listen0 方法,即可启动当前的 web 服务器实例:

    javascript 复制代码
    server.listen(80,()=>{
    	console.log('http server running at http://localhost')
    })

    案例代码

    javascript 复制代码
    //1.导入http 模块
    const http = require('http')
    //2.创建web服务器实例
    const server = http.createServer()
    
    //3.为服务器实例绑定request事件,监听客户端的请求
    server.on('request', function (req, res) {
        // console.log(req)
        console.log('request coming')
        // 设置响应头
        res.writeHead(200, {
            'Content-Type': 'text/html'
        });
    
        // 向浏览器发送响应内容
        res.end(`
        <!DOCTYPE html>
        <html lang="en">
        <head>
            <meta charset="UTF-8">
            <meta name="viewport" content="width=device-width, initial-scale=1.0">
            <title>Document</title>
        </head>
        <body>
            <h1>你好</h1>
        </body>
        </html>
        `);
    })
    
    //4.启动服务器
    server.listen(80, function () {
        console.log('server running at http://localhost')
    })

    如果端口占用,可以通过以下命令解决:

    "netstat -ano"是一个用于显示网络连接、路由表和网络接口信息的命令。这个命令的全称是"network statistics",其中各个部分的含义如下:

    • "net":网络
    • "stat":统计
    • "a":显示所有连接和监听端口
    • "n":以数字形式显示地址和端口号
    • "o":显示与每个连接相关的进程的PID (Process ID)

req请求对象

只要服务器接收到了客户端的请求,就会调用通过 server.on() 为服务器绑定的 request 事件处理函数。

如果想在事件处理函数中,访问与客户端相关的数据或属性,可以使用如下的方式:

javascript 复制代码
const http = require('http')

const server = http.createServer()

//req是请求对象,包含了与客户端相关的数据和属性


server.on('request', req => {
    //req.url是客户端请求的url地址
    const url = req.url
        //req.method是客户端请求的method类型
    const method = req.method
        //模板字符串,ES6 中新增的一种字符串表示方法。在模板字符串中,可以使用`${}`来插入变量或表达式
    const str = `Your request url is ${url},and request method is ${method}`

    console.log(str)
})

server.listen(80, () => {
    console.log('server running at http://127.0.0.1')
})

res响应对象

在服务器的 request 事件处理函数中,如果想访问与服务器相关的数据或属性

可以使用如下的方式

javascript 复制代码
server.on('request',(req, res) =>{
    // res 是响应对象,它包含了与服务器相关的数据和属性,例如:
    //要发送到客户端的字符串
    const str = `Your request url is ${req.url}, and request method is ${req.method}`
    // res.end() 方法的作用:
    // 向客户端发送指定的内容,并结束这次请求的处理过程
    res.end(str)
 })

案例代码

javascript 复制代码
const http = require('http')

const server = http.createServer()

//req是请求对象,包含了与客户端相关的数据和属性


server.on('request', (req, res) => {
    //req.url是客户端请求的url地址
    const url = req.url
        //req.method是客户端请求的method类型
    const method = req.method
        //模板字符串,ES6 中新增的一种字符串表示方法。在模板字符串中,可以使用`${}`来插入变量或表达式
    const str = `Your request url is ${url},and request method is ${method}`

    console.log(str)
        //调用res.end()方法,向客户端响应一些内容
    res.end(str)
})

server.listen(80, () => {
    console.log('server running at http://127.0.0.1')
})

解决中文乱码问题

当调用res.end()方法,向客户端发送中文内容的时候,会出现乱码问题,此时,需要手动设置内容的编码格式:

javascript 复制代码
server.on('request',(req.res)=>{
	//发送的内容包含中文
	const str = `您请求的url地址是${req.url},请求的类型method类型是${req.method}`
	//为了防止中文显示乱码问题,需要设置响应头Content-Type的值为text/html;charset=utf-8
	res.setHeader('Content-Type','text/html;charset=utf-8')
	//把包含中文的内容,响应给客户端
	res.end(str)
})

Content-Type: text/html 是指在 HTTP 头部中用来指示响应消息主体是 HTML 格式的内容类型。在 Web 开发中,常见的内容类型还包括:

  1. text/plain:纯文本格式
  2. application/json:JSON 格式
  3. application/xml:XML 格式
  4. image/jpeg:JPEG 图像格式
  5. audio/mpeg:MP3 音频格式
  6. video/mp4:MP4 视频格式
  7. application/pdf:PDF 文档格式

下面返回的内容就不会乱码了,res.setHeader设置响应字符集

javascript 复制代码
const http = require('http')

const server = http.createServer()

//req是请求对象,包含了与客户端相关的数据和属性


server.on('request', (req, res) => {
    //req.url是客户端请求的url地址
    const url = req.url
        //req.method是客户端请求的method类型
    const method = req.method
        //模板字符串,ES6 中新增的一种字符串表示方法。在模板字符串中,可以使用`${}`来插入变量或表达式
    const str = `Your request url is ${url},and request method is ${method}`

    console.log(str)
        //调用res.end()方法,向客户端响应一些内容
    res.setHeader('Content-Type', 'text/html;charset=utf-8')
    res.end(str + "乱码")
})

server.listen(80, () => {
    console.log('server running at http://127.0.0.1')
})

根据不同的url响应不同的html内容

分析核心实现步骤

  • 获取请求的 url 地址
  • 设置默认的响应内容为404 Not found
  • 判断用户请求的是否为/或 /index.html 首页
  • 判断用户请求的是否为/about.html 关于页面
  • 设置 Content-Type 响应头,防止中文乱码
  • 使用 res.end()把内容响应给客户端

动态响应内容

javascript 复制代码
server.on('request',function(req,res){
	const url = req.url		//1.获取请求的url地址
	let content = '<h1>404 Not found</h1>' //2.设置默认的内容为404 Not found
	if(url === '/' || url === 'index.html'){
		content = '<h1>首页</h1>'		//3.用户请求的是首页
	}else if(url === '/about.html'){
		content = '<h1>关于页面</h1>'  //4.用户请求的是关于页面
	}
	res.setHeader('Content-Type','text/html;charset=utf-8')//5.设置Content-Type响应头,防止中文乱码
	res.end(content)    //6.把内容发送给客户端
})

代码实现

javascript 复制代码
const http = require('http')

const server = http.createServer()

server.on('request', (req, res) => {
    //获取请求的url地址
    const url = req.url

    //设置默认响应的内容为404 Not found
    let content = '404 Not found!'

    //3.判断用户请求是否为/或index.html首页
    //4.判断用户请求的是否为/about.html首页
    if (url === '/' || url == '/index.html') {
        content = '<h1>首页</h1>'
    } else if (url === '/about.html') {
        content = '<h1>关于页面</h1>'
    }

    //5.设置Content-Type响应头,防止中文乱码
    res.setHeader('Content-Type', 'text/html;charset=utf-8')

    //6.使用res.end()把内容响应给客户端
    res.end(content)
})

server.listen(80, () => {
    console.log('server running at http://127.0.0.1')
})
相关推荐
我要洋人死15 分钟前
导航栏及下拉菜单的实现
前端·css·css3
龙哥说跨境27 分钟前
如何利用指纹浏览器爬虫绕过Cloudflare的防护?
服务器·网络·python·网络爬虫
科技探秘人27 分钟前
Chrome与火狐哪个浏览器的隐私追踪功能更好
前端·chrome
科技探秘人27 分钟前
Chrome与傲游浏览器性能与功能的深度对比
前端·chrome
JerryXZR33 分钟前
前端开发中ES6的技术细节二
前端·javascript·es6
七星静香35 分钟前
laravel chunkById 分块查询 使用时的问题
java·前端·laravel
q24985969338 分钟前
前端预览word、excel、ppt
前端·word·excel
小华同学ai43 分钟前
wflow-web:开源啦 ,高仿钉钉、飞书、企业微信的审批流程设计器,轻松打造属于你的工作流设计器
前端·钉钉·飞书
Gavin_9151 小时前
【JavaScript】模块化开发
前端·javascript·vue.js
pk_xz1234562 小时前
Shell 脚本中变量和字符串的入门介绍
linux·运维·服务器