【node】—— 手写一个404方案,前端请求不迷路谈及404界面,想必大家都不陌生,每当我们企图访问一个根本不存在的接
谈及404界面,想必大家都不陌生,每当我们企图访问一个根本不存在的接口时,网页就会跳转到404界面,这可谓是在编写接口请求过程中不可忽视的一大特色,不得不品鉴。
那么接下来,我就会通过一个接口请求实例,来分析涉及404如何产生的node中web服务,以及实现跳转404界面的调用过程。
打造一个接口
首先要做的无疑是,先在终端通过执行npm init -y
初始化一个node项目,然后编写正常流程下的接口三件套:
- 通过
const http = require('http')
引入http模块 - 通过
const serve = http.createServer()
创建一个名为serve
的服务,其中自带req
请求体,res
响应体。 - 通过
serve.listen
将整个服务部署在3000端口,并监听这个端口。
const http = require('http'); // 引入http模块
// 创建一个服务内置req请求体,res响应体。
const serve = http.createServer((req, res) => {
res.end('hellow world')
})
// 服务部署在3000端口,通过serve.listen监听端口
serve.listen(3000, () => {
console.log('listening on port 3000'); // 部署成功会输出listening on port 3000
})
这样一来我们就完成了这个接口请求的空壳,其中第五行的res.end()
是res
内置的一个方法,作用是向前端输出括号中内容。

可以看到我们的服务正常在3000端口上运行起来了。
值得一提的是,如果同一个网络下的另一台设备想要请求这个端口,可以通过在自己设备上任意一个终端输入ipconfig
,便可以得到自己被分发到的ip网址,供他人访问。


做到不同的网址返回不同界面
可以看到,我们现在运行的代码就像是一个后端服务器,不断的接收着前端网页发送的请求,那当我们想要访问这个接口的其他地址时,我们自然得返回不同的界面。
第一步:获取前端请求的地址
于是,我们又得引入url
模块,其中的url.parse
方法可以将req.url
(得到前端请求地址的方法,为字符串形式)字符串转变成标准的路径(url对象),然后我们进行输出:
const http = require('http'); // 引入http模块
const url = require('url'); // 引入url模块
// 创建一个服务内置req请求体,res响应体。
const serve = http.createServer((req, res) => {
const reqUrl = url.parse(req.url); // 解析前端的请求地址
console.log(reqUrl); // 输出这个地址
res.end('hellow world');
})
// 服务部署在3000端口,通过serve.listen监听端口
serve.listen(3000, () => {
console.log('listening on port 3000'); // 部署成功会输出listening on port 3000
})
就比如说我请求的地址为localhost:3000/user
,那么在网页上刷新一下,终端就会以数组的形式得到请求的地址名。

第二步:对应的网址输出对应的界面
既然我们获取到了前端传来的请求网址,我们自然可以编写相应的输出项,最简便的方法就是通过if
进行判断。
那么比如,当我们被请求头地址'/'
时,输出的就是一段html
文本。

当我们被请求地址'/user'
时,输出的就是一段html
文本。

当前端发送的是POST
请求,且被请求地址为'/login'
时,输出的就是“登陆成功”。

以下是完整代码:
const http = require('http'); // 引入http模块
const url = require('url'); // 引入url模块
const data = {
id: 1,
name: '小明',
age: 18
}
// 创建一个服务内置req请求体,res响应体。
const serve = http.createServer((req, res) => {
const reqUrl = url.parse(req.url); // 解析前端的请求地址
if(reqUrl.path === '/') {
res.writeHead(200, { 'Content-Type': 'text/html' }) // 响应头:告诉前端接下来的内容为html文本
res.end('<h2>hellow world</h2>');
}else if(reqUrl.pathname === '/user'){
res.writeHead(200, {'content-type': 'application/json; charset=utf-8'}) // 接下来的内容为JSON
res.end(JSON.stringify(data)); // 转换成字符串
}else if(req.method === 'POST' && reqUrl.pathname === '/login'){
// 第一步:拿到前端传递的参数
// 第二步:区数据库里面校验该参数的合法性
res.end('登陆成功');
}
})
// 服务部署在3000端口,通过serve.listen监听端口
serve.listen(3000, () => {
console.log('listening on port 3000'); // 部署成功会输出listening on port 3000
})
加入跳转404界面功能
终于,轮到我们万众瞩目的404界面的登场!
其实我们有了上面的基础,便能很容易得出,当前端访问后端没有设置的地址时,我们只需在原来的基础上再添加一个else
来控制它跳转到404界面。
于是我们在原来的基础上引入fs
模块用于操作文件的增删改查,与path
模块用于拼接得到跳转404的路径。
const http = require('http');
const url = require('url');
const fs = require('fs');
const path = require('path');
const data = {
name: '张',
age: 18,
}
const serve = http.createServer((req, res) => {
const reqUrl = url.parse(req.url);
if(reqUrl.path === '/') {
res.writeHead(200, { 'Content-Type': 'text/html' })
res.end('<h2>hellow world</h2>');
}else if(reqUrl.pathname === '/user'){
res.writeHead(200, {'content-type': 'application/json; charset=utf-8'})
res.end(JSON.stringify(data));
}else if(req.method === 'POST' && reqUrl.pathname === '/login'){
// 第一步:拿到前端传递的参数
// 第二步:区数据库里面校验该参数的合法性
res.end('登陆成功');
}
else {
const _url = path.resolve(__dirname, 'assets/404.html') // 拼接根目录的绝对路径和404的html路径
const content = fs.readFileSync(_url, { encoding: 'utf-8'}) // 以utf-8编码方式读取这个文件,
res.end(content)
}
})
serve.listen(3000, () => {
console.log('listening on port 3000');
})
那么现在,面对那些不存在的网址请求,我们就能将其跳转到自己编写的html页面中:

至此,一个404跳转方案便大功告成!
补充:利用Koa实现项目简化
在实际使用过程中,自然少不了利用封装函数对项目的简化,于是我们通过npm i koa
安装koa
框架。从而实现这样的简化:
在第一个js文件中,我们把创建端口与引入路由的代码编写在其中。
const Koa = require('koa'); // 引入koa模块
const app = new Koa(); // 得到框架的实例对象
const router = require('./router/router.js'); // 引入接口文件
app.use(router.routes()); // 让路由生效
app.listen(3000, () => {
console.log('项目已经启动')
})
下一步就是通过npm i koa-router
安装路由,然后另起一个js文件,在其中编写那些需要用到的接口:
const router = require('koa-router')() // 使用必须先调用一下
router.get('/', (ctx) => {
ctx.body = 'hellow world'
})
router.get('/user', (ctx) => {
ctx.body = {
name: '小明',
age: 18
}
})
module.exports = router // 抛出router对象
可以看到每一个地址都能在这里编写相应的地址内容,并且比之前的代码更加美观整洁。
这种引入框架的好处就是不必编写繁琐的代码,以及省去大量的if else
来进行判断。
转载自:https://juejin.cn/post/7406992576514474022