渲染静态页面、get请求、post请求、express框架、路由、中间件

1. 渲染静态页面

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

http.createServer((request,response)=>{
    
    
    // 将请求的路由取出来  不携带参数
    let requestUrl = url.parse(request.url).pathname;
    // 如果是小图标  直接返回
    if (requestUrl == '/favicon.ico'){
    
    
        return false;
    }
    // 获取本次请求文件的后缀名  来确定请求的类型
    let extname = path.extname(requestUrl);
    // 使用后缀名  确定响应类型
    let mime = getMime(extname);
    fs.readFile('./xiaou' + requestUrl,(error,data)=>{
    
    
        if (error){
    
    
            console.log(error);
        }else{
    
    
            response.writeHead(200,{
    
    'Content-type':mime});
            response.end(data);
        }
    })

}).listen(3000,'127.0.0.1',()=>{
    
    
    console.log('服务器正在运行......');
})

function getMime(name){
    
    
    switch (name){
    
    
        case '.html':
            return 'text/html';
        case '.css':
            return 'text/css';
        default:
            return 'text/plain';
    }
}

2. get请求

        let query = url.parse(request.url).query;
        // querystring模块中有一个parse方法  他能将get参数转化为对象格式
        let userObj = qs.parse(query);
        // 想userObj中追加属性  追加黑名单
        userObj.blacklist = 1;
        // 将原有数据读取出来  并将其转化为数组
        let userArr = JSON.parse(readPageFile('./data/user.json',200,response));
        // 给添加的数据追加ID
        userObj.id = userArr[userArr.length - 1].id + 1;
        // 向数组中追加数据
        userArr.push(userObj);
        // 将数组写入到JSON中  覆盖写
        response.writeHead(200,{
    
    'Content-type':'text/html;charset=utf-8'});
        fs.writeFile('./data/user.json',JSON.stringify(userArr),{
    
    encoding:'utf-8',flag:'w'},err=>{
    
    
            err ? console.log(err) : response.end('注册成功');
        })

3. post请求

        // 定义一个空数组  准备装取post数据
        let arr = [];
        // post方式提交  使用事件驱动  两个事件  一个是data事件  一个是end事件
        // 使用request对象触发data事件  第一个参数是事件名data
        // 第二个参数是回调函数  回调内置一个参数  参数是传输的数据  post数据
        request.on('data',(chunk)=>{
    
    
            arr.push(chunk);
        })
        // 使用end事件结束post传参
        request.on('end',()=>{
    
    
            // 获取post数据
            let query = Buffer.concat(arr).toString();
            // querystring模块中有一个parse方法  他能将get参数转化为对象格式
            let userObj = qs.parse(query);
            // 将所有的用户取出来  并转化为数组
            let userArr = JSON.parse(readPageFile('./data/user.json',200,response));
            // 匹配登录  使用find方法进行查找数据是否存在
            // userObj.username  :  登录者的用户名
            // element.username  :  所有已注册的用户名
            let result = userArr.find(element=>element.username == userObj.username);
            // 判断
            if (result == undefined){
    
    
                response.writeHead(200,{
    
    'Content-type':'text/html;charset=utf-8'});
                response.end("<script>alert('用户名不存在  请先去注册');location.href='http://127.0.0.1:3000/register'</script>")
            }else{
    
    
                if (result.blacklist == 0){
    
    
                    response.writeHead(200,{
    
    'Content-type':'text/html;charset=utf-8'});
                    response.end("<script>alert('用户已遭多人投诉  你懂');location.href='http://127.0.0.1:3000/login'</script>")
                }else{
    
    
                    if (result.password != userObj.password){
    
    
                        response.writeHead(200,{
    
    'Content-type':'text/html;charset=utf-8'});
                        response.end("<script>alert('密码错误');location.href='http://127.0.0.1:3000/login'</script>")
                    }else{
    
    
                        response.writeHead(200,{
    
    'Content-type':'text/html;charset=utf-8'});
                        response.end("<script>alert('登录成功');location.href='http://127.0.0.1:3000/index'</script>")    
                    }
                }
            }
        })

整体案例

const http = require('http');
const fs = require('fs');
const url = require('url');
const path = require('path');
const qs = require('querystring');


http.createServer((request,response)=>{
    
    
    let requestUrl = url.parse(request.url).pathname;
    if (requestUrl == '/favicon.ico'){
    
    
        return false;
    }
    if (requestUrl == '/'){
    
    
        requestUrl = '/index';
    }
    if (requestUrl == '/index'){
    
    
        response.end(readPageFile('./view/home.html',200,response));
    }else if (requestUrl == '/login'){
    
    
        response.end(readPageFile('./view/dl.html',200,response));
    }else if (requestUrl == '/register'){
    
    
        response.end(readPageFile('./view/zc.html',200,response));
    }else if (requestUrl == '/insert'){
    
    
        let query = url.parse(request.url).query;
        // querystring模块中有一个parse方法  他能将get参数转化为对象格式
        let userObj = qs.parse(query);
        // 想userObj中追加属性  追加黑名单
        userObj.blacklist = 1;
        // 将原有数据读取出来  并将其转化为数组
        let userArr = JSON.parse(readPageFile('./data/user.json',200,response));
        // 给添加的数据追加ID
        userObj.id = userArr[userArr.length - 1].id + 1;
        // 向数组中追加数据
        userArr.push(userObj);
        // 将数组写入到JSON中  覆盖写
        response.writeHead(200,{
    
    'Content-type':'text/html;charset=utf-8'});
        fs.writeFile('./data/user.json',JSON.stringify(userArr),{
    
    encoding:'utf-8',flag:'w'},err=>{
    
    
            err ? console.log(err) : response.end("<script>alert('注册成功');location.href='http://127.0.0.1:3000/login'</script>");
        })
    }else if (requestUrl == '/loginto'){
    
    
        // 定义一个空数组  准备装取post数据
        let arr = [];
        // post方式提交  使用事件驱动  两个事件  一个是data事件  一个是end事件
        // 使用request对象触发data事件  第一个参数是事件名data
        // 第二个参数是回调函数  回调内置一个参数  参数是传输的数据  post数据
        request.on('data',(chunk)=>{
    
    
            arr.push(chunk);
        })
        // 使用end事件结束post传参
        request.on('end',()=>{
    
    
            // 获取post数据
            let query = Buffer.concat(arr).toString();
            // querystring模块中有一个parse方法  他能将get参数转化为对象格式
            let userObj = qs.parse(query);
            // 将所有的用户取出来  并转化为数组
            let userArr = JSON.parse(readPageFile('./data/user.json',200,response));
            // 匹配登录  使用find方法进行查找数据是否存在
            // userObj.username  :  登录者的用户名
            // element.username  :  所有已注册的用户名
            let result = userArr.find(element=>element.username == userObj.username);
            // 判断
            if (result == undefined){
    
    
                response.writeHead(200,{
    
    'Content-type':'text/html;charset=utf-8'});
                response.end("<script>alert('用户名不存在  请先去注册');location.href='http://127.0.0.1:3000/register'</script>")
            }else{
    
    
                if (result.blacklist == 0){
    
    
                    response.writeHead(200,{
    
    'Content-type':'text/html;charset=utf-8'});
                    response.end("<script>alert('用户已遭多人投诉  你懂');location.href='http://127.0.0.1:3000/login'</script>")
                }else{
    
    
                    if (result.password != userObj.password){
    
    
                        response.writeHead(200,{
    
    'Content-type':'text/html;charset=utf-8'});
                        response.end("<script>alert('密码错误');location.href='http://127.0.0.1:3000/login'</script>")
                    }else{
    
    
                        response.writeHead(200,{
    
    'Content-type':'text/html;charset=utf-8'});
                        response.end("<script>alert('登录成功');location.href='http://127.0.0.1:3000/index'</script>")    
                    }
                }
            }
        })
    }else{
    
    
        response.end(readPageFile('./view/404.html',404,response));
    }
}).listen(3000,'127.0.0.1',()=>{
    
    
    console.log('服务器正在运行......');
})

// 读取页面的函数
function readPageFile(pageUrl,status = 0,response = {
    
    }){
    
    
    response.writeHead(status,{
    
    'Content-type':'text/html'});
    return fs.readFileSync(path.resolve(__dirname,pageUrl),'utf-8');
}

4. express框架

简介

​ Express 是一个简洁而灵活的 Node.js Web应用框架, 提供一系列强大特性帮助你创建各种Web应用

​ 如果不计中间件,主体框架只有一千余行代码,非常简练

​ Express 不对 Node.js 已有的特性进行二次抽象,我们只是在它之上扩展了Web应用所需的功能

​ Express内部还是使用的http模块实现服务器创建和监听, 对http模块进行了二次封装

​ express自身内部只是扩展了路由和中间件

使用

​ 下载express模块, 命令 npm install express

​ 在.js文件中, 引入express模块 初始化服务器对象

​ 设置路由接口地址 (以供浏览器访问) 监听端口号 (给服务器设置端口号)

5. 路由

路由组成

​ URL目录部分太长了, 可以让后台规定路由的路径(/api/getNew), 然后当访问时, 让后台去转发寻找

​ 例如: 访问 /image/rB.jpg 就相当于 访问的是上面的路径资源 (但是具体访问什么, 还是后台说了算)

​ 不同的路径, 对应的不同路由 (路由 = 路径)

​ 所以所有的请求, 都看后台如何处理

​ API接口 = 路由 = 路径 = url地址

路由动态

​ get路由 : 只能通过get方式进行访问

​ post路由 : 只能通过post方式进行访问

​ all路由 : 可以使用任何方式进行访问

​ use路由 : 可以使用任何方式进行访问

const express = require('express');

// console.log(express);
// 实例化一个应用  使用这个应用
const app = express();
// console.log(app);

// 使用express创建一个路由  get方法
app.get('/index',(request,response)=>{
    
    
    // 在express中  我们响应数据使用send方法  注意  send和end一样  只能响应字符串
    response.send('第一个程序');
});

// 使用post方法创建一个路由
app.post('/ppp',(request,response)=>{
    
    
    response.send('第二个程序  这是post');
})

// 使用all方法  接受所有的方式
app.all('/all',(request,response)=>{
    
    
    response.send('这是第三程序  可以接受任何');
})

// 使用use中间件  接受任何方式
// app.use('/uuu',(request,response)=>{
    
    
//     response.send('这是use方法');
// })
app.use((request,response)=>{
    
    
    response.send('404');
})

// 监听
app.listen(3000,'127.0.0.1',()=>{
    
    
    console.log('服务器正在运行......');
})

路径正则

​ ? 匹配0个或者1个字符 ?前边的

​ + 匹配1个或多个+号前边的字符

​ * 通配符 匹配0个或者多个 *所在的位置

​ () 将里边的字符算作一个整体

​ 正则匹配路由

const express = require('express');

const app = express();

// 定义路由
// 正则表达式匹配路由
// ?  :  零次或一次匹配其前字符
// app.get('/ab?cd',(request,response)=>{
    
    
//     response.send('匹配成功');
// })

// +  :  一次或多次匹配其前字符  至少一次
// app.get('/ab+cd',(request,response)=>{
    
    
//     response.send('匹配成功');
// })

// ()  :  将括号中当成一个整体
// app.get('/a(bc)?d',(request,response)=>{
    
    
//     response.send('匹配成功');
// })

// *  :  零次、一次或多次匹配*所在位置
// app.get('/ab*cd',(request,response)=>{
    
    
//     response.send('匹配成功');
// })

// 正则表达式匹配
app.get(/a/,(request,response)=>{
    
    
    response.send('匹配成功');
})

app.listen(3000,'127.0.0.1',()=>{
    
    
    console.log('服务器正在运行');
})

路径参数解析

​ 携带参数的路由 参数以:分开

​ 路径参数是命名的url字段 用于捕获在url中的位置

​ 捕获的值放在req.params中 路径的:user_id user_id对象的键

const express = require('express');

const app = express();

// 定义路由
/*
    在使用路由传递参数的时候  和get参数差不多
    都是通过地址栏进行传递参数  但是还是有些不同的   至于不同点
    在路由传参中  我们在浏览器端  不需要在使用?进行传递参数  只需要直接传递就可以了
    在我们后端接受参数的时候  不需要使用url或者query等方法
    我们直接使用:参数名就可以了
    直接定义在路由中

    在后台接受到参数的时候  我们的参数存储在request对象中的params属性中
    他是一个属性  也是一个对象  对象中的数据就是路由参数
    是键值对的形式存在的   如果说没有传参  没有参数  那么默认值是空对象

*/
app.get('/index/:name/:age',(request,response)=>{
    
    
    let {
    
    name,age} = request.params;
    console.log(request.params);
    console.log(name,age);
    response.send('你好  兔头');
})

app.listen(3000);

路由级别路由

​ 也就是我们说的二级路由

​ 一个网站中至少有几十个路由 不能都写在一个页面 那样读取困难 优化不好

​ 所以说 我们每一个模块的路由都是分开写的 分别写在不同的路由模块中

​ 定义路由模块 我们需要使用到express中的Router对象

6. 中间件

什么是中间件

​ Express是一个自身功能极简,完全是路由和中间件构成一个web开发框架

​ 一个Express应用就是在调用各种中间件。中间件在Express开发中很重要

​ 中间件函数能够访问请求对象 (req)、响应对象 (res) 以及应用程序的请求/响应循环中的下一个中间件函数

​ 该next功能是中间件函数中的一个功能,当被调用时,它将执行当前中间件之后的中间件

​ 下一个中间件函数通常由名为 next 的变量来表示

内置中间件

​ 内置中间件我们只使用一个 使用static

​ static : 渲染静态资源的中间件

​ urlencode : 使用第三方中间件完成功能 接受表单数据

​ json : 使用第三方中间件完成功能 接受JSON数据

const express = require('express');
const path = require('path');

const app = express();

// 使用static渲染进行资源
// 使用use中间件进行渲染
// 内置一个或者两个参数
// 第一个参数是路由  可选
// 第二个参数是express.static方法  方法内置一个参数  参数是渲染的资源路径
// 主要的作用是渲染CSS  JS  IMAGE等静态资源
// app.use(express.static('../xiaou/'));
app.use('/xiaou',express.static(path.resolve(__dirname,'../xiaou/')));

app.listen(3000,'127.0.0.1',()=>{
    
    
    console.log('服务器正在运行......');
})

错误处理中间件

​ status : 处理http响应码

​ send : 处理404

自定义中间件

​ 自定义中间件是自己定义的中间件 使用同名路由

​ 路由中没有响应 需要使用next调用下一个中间件

​ 最后一个路由将其直接响应出去

const express = require('express');

const app = express();

// 自定义中间件中  回调函数中可以传递第三个参数
// 在自定义中间键中  有若干个路由  但是都是一个名字  不能有响应
// 但是可以有next   使用next方法调用下一个同名中间件
app.use('/index',(request,response,next)=>{
    
    
    let hotSearch = [
        {
    
    name : '口红'},
        {
    
    name : '面膜'},
        {
    
    name : '项链'},
        {
    
    name : '箱包'},
        {
    
    name : '高跟鞋'},
        {
    
    name : '防晒霜'},
        {
    
    name : '耳钉'},
        {
    
    name : '搓衣板'}
    ];
    request.hotSearch = hotSearch;
    next();
})
app.use('/index',(request,response,next)=>{
    
    
    let first = [
        {
    
    name : '导弹'},
        {
    
    name : '原子弹'},
        {
    
    name : '氢弹'},
        {
    
    name : '达姆弹'},
        {
    
    name : '荷包蛋'},
        {
    
    name : '茶叶蛋'},
        {
    
    name : '混蛋'},
        {
    
    name : '滚蛋'}
    ];
    request.first = first;
    next();
})

app.use('/index',(request,response)=>{
    
    
    let footer = [
        {
    
    name : '优就业'},
        {
    
    name : '中公教育'},
        {
    
    name : '腾讯'},
        {
    
    name : '网易'},
        {
    
    name : '饿了吗'},
        {
    
    name : '美团'},
        {
    
    name : '赶集网'},
        {
    
    name : '智联'}
    ];
    let arr = [request.hotSearch,request.first,footer];
    response.send(arr);
})

app.listen(3000,'127.0.0.1',()=>{
    
    
    console.log('服务器正在运行......');
})

第三方中间件

​ 第三方中间件使用的其实就是第三方模块

​ 依赖于express的第三方模块就是express的中间件

​ 常用的第三方中间件有

​ body-parser

​ cookie-parser

​ express-session

​ multer

​ crypto

​ ejs

​ pug

​ nodemon

猜你喜欢

转载自blog.csdn.net/yangyanqin2545/article/details/112762059
今日推荐