node.js服务器动态资源处理

news2024/11/30 11:52:44

一、node.js服务器动态资源处理与静态资源处理的区别?

静态与动态服务器主要区别于是否读取数据库,若然在数据库中的资料处理中将数据转换成可取用格式的结构,也就是说把对象转化为可传输的字节序列过程称为序列化,反之则为反序列化。

简单来说,它比起静态资源较复杂,因为它会随用户不同、响应内容不同而不断产生变化

二、什么是动态资源处理?

以JSON与JS为例,JSON.stringify()对数据序列化,JSON.parse()对数据反序列化。动态处理也就是对数据进行重新排序来读写数据库,读取反序列化,写入序列化。

三、处理动态资源的方法?

将页面内容动态化。使用到第三方模块——>模板引擎  去动态将我的数据嵌入到我的网页中去。

什么是模板引擎?见 http://t.csdnimg.cn/lzedW

四、代码示例。

(1)我们将首页、登录、注册三个html静态页面和用户列表users.html写在views这个大文件夹下。css样式和images图片放入public这个大文件夹下。创建一个data大文件夹,data下面建一个user.json文件来专门存储用户数据
简单写一下首页、注册、登录页面的html静态页面的样式。此处省略。具体见我上篇博客见 http://t.csdnimg.cn/zXWW7

动态资源处理具体表现就是我的用户列表渲染功能(users.html)和我的不同错误提示功能(404.html)。

用户列表渲染功能可以将我的user.json里面注册成功的用户数据渲染到我的服务器用户列表页面

users.html 用户列表:

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>用户列表</title>
  <link rel="stylesheet" href="../public/css/main.css">
</head>
<body>
  <h1>用户列表</h1>
  <img src="../public/images/01.png" alt=""><br>
  <ul>
    <!-- 循环li -->
    <% for(let username in users){ %>
    <li>
        <!-- 取出属性名和密码这个属性值,放入li里面 -->
        <%=username %> : <%=users[username] %>
    </li>
    <% } %>
  </ul>
</body>
</html>

404.html  不同错误提示:

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>404</title>
</head>
<style>
  body {
    background-color:pink;
  }
</style>
<body>
  <h1>
    <!-- 定义模板 -->
    <%= msg %>
  </h1>
</body>
</html>

(2)在我的测试代码的终端 npm install underscore -save安装underscore渲染模板引擎

(3) 测试代码如下:

const http = require('http');
const fs = require('fs');
const path = require('path');
const url = require('url');
// 声明一个专门存放所有用户的变量
var users;
// 导入查询参数的模块
const querystring = require('querystring');
// 导入underscore渲染模板
const _ =require('underscore');
//使用underscore渲染模板
function render(data){
    // 读取模板内容
    let temp=fs.readFileSync(path.join(__dirname,'views/404.html'));
    // 获取渲染函数
    let compiled=_.template(temp.toString());
    // 渲染模板
    return compiled(data); 
}
//创建服务器
const server = http.createServer();
//读取文件。读取user.json存放用户数据的文件
fs.readFile(path.join(__dirname, 'data/users.json'), (err, data) => {
    if (err) {
        users = {};
    } else {
        users = JSON.parse(data.toString()); //如果读取正确就将读到的内容转换为一个对象存到users里
    }
})
//服务器做出请求响应
server.on('request', (req, res) => {
    let objurl = url.parse(req.url); //将url转为一个对象才能获取到它的pathname
    let pathname = objurl.pathname;
    // 对pathname做处理
    if (pathname.startsWith('/public')) {
        // 找到当前项目文件夹,再将相对路径转为绝对路径
        let p = path.join(__dirname, pathname);
        fs.readFile(p, (err, data) => {
            if (err) {
                res.end(render({msg:'访问的文件不存在'})); //可以使用中文,因为现在是html页面去显示的
            } else {
                res.end(data);
            }
        })
    } else if (pathname == '/' || pathname == '/home') {
        let p = path.join(__dirname, 'views/index.html');
        fs.readFile(p, (err, data) => {
            if (err) {
                res.end(render({msg:'访问的文件不存在'}));
            } else {
                res.end(data);
            }
        })
    } else if (pathname == '/regist') { //建一个文件夹data专门来储存数据 里面建一个users.json的文件
        let p = path.join(__dirname, 'views/regist.html');
        fs.readFile(p, (err, data) => {
            if (err) {
                res.end(render({msg:'访问的文件不存在'}));
            } else {
                res.end(data);
            }
        })

    } else if (pathname == '/login') {
        let p = path.join(__dirname, 'views/login.html');
        fs.readFile(p, (err, data) => {
            if (err) {
                res.end(render({msg:'访问的文件不存在'}));
            } else {
                res.end(data);
            }
        })
    } else if (pathname == '/doRegist') {
        // Node.js 的 querystring 模块用于解析和格式化 URL 查询字符串:
        // 1. 将字符串参数解析成对象
        // querystring.parse(url)
        // 2. 将对象参数解析成字符串
        // querystring.stringify(urlObject)
        let query = querystring.parse(objurl.query);
        let username = query.username;
        let password = query.password;
        if (users[username]) {
            res.end(render({msg:'用户名已存在,不能注册!'}));
        } else {
            //因为users里面是一个对象。所以只能属性名=值的形式。故属性名 = 密码(密码相当于这个属性名对应的属性值)
            users[username] = password;
            //利用JSON.stringify(users)将users对象转为字符串重新写到文件里去
            fs.writeFile(path.join(__dirname, 'data/users.json'), JSON.stringify(users), (err) => {
                if (err) {
                    res.end(render({msg:'注册失败'}));
                } else {
                    res.end(render({msg:'注册成功'}));
                }
            })

        }

    } else if (pathname == '/doLogin') {
        let query = querystring.parse(objurl.query);
        let username = query.username;
        let password = query.password;
        // 判断users的用户名和密码有无
        if (users[username] && users[username] == password) { //用户名 && 密码
            res.writeHead(200, { 'Content-Type': 'text/html;charset=utf-8' });
            res.end(render({msg:'登录成功'}));
        } else {
            res.writeHead(502, { 'Content-Type': 'text/html;charset=utf-8' });
            res.end(render({msg:'用户名或密码错误,登录失败'}));
        }
    } else if (pathname == '/list') {
        let p=path.join(__dirname,'views/users.html');
        fs.readFile(p,(err,data)=>{
            if(err){
                res.end(render({msg:'访问的文件不存在'}));
            }else{
                //获得渲染函数 
                let compiled=_.template(data.toString()); 
                // 调用渲染函数来生成html内容
                let html=compiled({users:users}); //我们在模板里取的是users的属性,所以不能简写成users,而是users:users
                res.end(html);
                
            }
        })
    }
});

server.listen(3000, '127.0.0.1', () => {
    console.log('Server is running at http://127.0.0.1:3000');
})

(4)结果显示

4-1》当我的用户数据已被注册时:

动态显示我的404.html页面

4-2》我完成用户注册时,我点击用户列表,显示结果如下:

(5)综上所述,相比我的静态资源处理而言,我的动态资源处理就相对效率较高,对于不同的错误信息,我可以直接使用我的404.html模板,直接在我的运行代码中显示 res.end(render({msg:'错误内容'})); 并且我可以直接使用用户数据模板user.html使用<% %> 执行javascript代码。可以直接在我的服务器端页面展示我的所有成功注册的用户数据。化繁为简。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1602854.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

她在《繁花》大放异彩,“浪姐”暴瘦15斤,打脸了不看好她的观众

不知不觉&#xff0c;《浪姐》已经迎来第5季了。播到第4季的时候&#xff0c;改名成《乘风破浪2023》&#xff0c;这一季叫《乘风2024》&#xff0c;和前几季相比&#xff0c;热度依然不减。 都说3个女人一台戏&#xff0c;更何况这个节目&#xff0c;每次能请到30位姐姐&…

再生龙(Clonezilla)网络克隆linux系统实现迁移——筑梦之路

官方网站&#xff1a;Clonezilla - 簡介 环境说明 源端&#xff1a;CentOS 7 操作系统的虚拟机&#xff0c;硬盘大小为 40GiB&#xff0c;分为 1GiB 的 /boot&#xff08;启动&#xff09;分区、4GiB 的 swap&#xff08;交换&#xff09;分区和 35GiB 的 /&#xff08;根&…

LeetCode236:二叉树的最近公共祖先

题目描述 给定一个二叉树, 找到该树中两个指定节点的最近公共祖先。 百度百科中最近公共祖先的定义为&#xff1a;“对于有根树 T 的两个节点 p、q&#xff0c;最近公共祖先表示为一个节点 x&#xff0c;满足 x 是 p、q 的祖先且 x 的深度尽可能大&#xff08;一个节点也可以是…

二分查找的时间复杂度的讲解

二分查找的代码&#xff1a; 二分查找的时间复杂度&#xff1a; 最坏的情况&#xff1a; 就是找不到和查找区间只剩一个值的时候&#xff0c;这两种都是最坏的结果&#xff0c;假设查找了x次&#xff0c;达到了最坏的结果&#xff1a; N代表每一次折半区间数据的个数&#xf…

【C语言】——字符串函数的使用与模拟实现(下)

【C语言】——字符串函数的使用与模拟实现&#xff08;下&#xff09; 前言五、长度受限类字符串函数5.1、 s t r n c p y strncpy strncpy 函数5.2、 s t r n c a t strncat strncat 函数5.3、 s t r n c m p strncmp strncmp 函数 六、 s t r s t r strstr strstr 函数6.1、函…

20240329-1-SVM面试题

SVM面试题 1. SVM直观解释 SVM&#xff0c;Support Vector Machine&#xff0c;它是一种二分类模型&#xff0c;其基本模型定义为特征空间上的间隔最大的线性分类器&#xff0c;间隔最大使它有别于感知机&#xff1b;其还包括核技巧&#xff0c;这使它成为实质上的非线性分类…

使用SpringBoot将中国地震台网数据保存PostGIS数据库实践

目录 前言 一、数据转换 1、Json转JavaBean 2、JavaBean与数据库字段映射 二、空间数据表设计 1、表结构设计 三、PostGIS数据保存 1、Mapper接口定义 2、Service逻辑层实现 3、数据入库 4、运行实例及结果 总结 前言 在上一篇博客中基于Java的XxlCrawler网络信息爬…

解决yarn第一次使用无法运行的问题

报错&#xff1a; yarn : 无法加载文件 D:\program software\NVM\nvm\v16.20.0\yarn.ps1&#xff0c;因为在此系统上禁止运行脚本。有关详细信息&#xff0c;请参阅 https:/go.microsoft.com/fwlink/?LinkID135170 中的 about_Execution_Policies。 所在位置 行:1 字符: 1 …

鲲鹏920RDMA应用示例代码

当前针对鲲鹏920服务器&#xff0c;编写了RDMA通信传输代码&#xff0c;首先采用TCP socket进行管理信息获取&#xff0c;然后调用verbs函数接口进行数据传输。需要安装rdma-core-devel库才可以编译 代码如下&#xff1a; /** rdma_lib.h** Created on: 2021年1月1日* A…

java激活

此破解码适合2023所有版本 找到idea64.exe.vmoption添加下面三行 链接:破解包下载 提取码:jqw1

软件工程 考研复试常考知识点总结

软件工程 什么是软件工程&#xff0c;这门课讲的什么&#xff1f; 软件工程就是把软件的开发、运行、维护的各个阶段进行系统化和规范化的过程&#xff0c;也就是把工程化的方法运用在软件技术之中&#xff0c;以构建和维护高质量的软件。 进一步&#xff0c;什么是工程化思想…

0基础学习SQL注入之万能账号密码(BUUctf例题-[极客大挑战 2019]EasySQL1)

做题 借助例题[极客大挑战 2019]EasySQL1来理解SQL注入中的万能账号密码。 我们现解题&#xff0c;解题过程中的知识点在后面都会说到。 打开网址&#xff0c;我们看到的是这个界面。根据题目提示应该是属于SQL注入类型的 1.寻找注入点&#xff0c;很明显&#xff0c;输入用…

JDK17的Mybatis-Plus报错问题

添加 --add-opens java.base/java.langALL-UNNAMED

物理机安装centos7并配置基本环境,网络配置,docker配置

1.首先下载镜像Download 2.下载UltraISO 安装docker 第1步&#xff1a;卸载当前版本docker yum erase docker \docker-client \docker-client-latest \docker-common \docker-latest \docker-latest-logrotate \docker-logrotate \docker-selinux \docker-engine-selinux \do…

unity制作拼接地图

前段时间有个朋友问我想要制作一款地图编辑器&#xff0c;最开始我还想着在一个平面用节点切割制作地图编辑器这倒是也行&#xff0c;但不太好控制每一个点&#xff0c;如果未来项目大了&#xff0c;更加不好维护。 偶然间翻到一篇文章&#xff1a;unity地图边缘检测 或许我们…

升级啦!探索全新 StarRocks 中文社区与高效使用秘籍!

眼尖的朋友可能已经注意到&#xff0c;StarRocks 中文社区最近换上了全新的皮肤。是的&#xff0c;我们 StarRocks 的聚集地升级了&#xff01;&#x1f389; 自成立两年半以来&#xff0c;StarRocks 中文社区不断壮大&#xff0c;现已发展成为一个拥有数万名成员的活跃社区。…

2024年团队程序设计天梯赛模拟赛 L1 + L2

目录 L1 - 6 剪切复制 L1 - 8 小偷踩点 L2 - 1 推宝塔 L2 - 2 含茶量 L2 - 3 到底爱不爱我 L2 - 4 寻宝图 L1 - 6 剪切复制 使用计算机进行文本编辑时常见的功能是剪切功能&#xff08;快捷键&#xff1a;Ctrl X&#xff09;。请实现一个简单的具有剪切和粘贴功能的文本…

MSSQL 命令行操作说明 sql server 2022 命令行下进行配置管理

说明&#xff1a;本文的内容是因为我在导入Access2019的 *.accdb 格式的数据时&#xff0c;总是出错的背景下&#xff0c;不得已搜索和整理了一下&#xff0c;如何用命令行进行sql server 数据库和用户管理的方法&#xff0c;作为从Access2019 直接导出数据到sql server 数据库…

低噪声放大器是如何实现低噪声放大的功能的

灵敏度作为接收机最重要的指标之一,直接决定了接收机能分辨的最小信号。接收机的灵敏度计算公式如下所示。 Psensitivity=-174dBm+NF+10*lg(BW)+SNR 由接收机灵敏度的计算公式可知,影响接收机灵敏度的指标有噪声系数、带宽和信噪比,因此一旦带宽和信噪比确定了,那么能决…

图像基础—图像分类

图像通常分为二值图像、灰度图像和彩色图像 图 1-3 二值图像、灰度图像和彩色图像 &#xff08;1&#xff09;二值图像 二值图像又称为黑白图像&#xff0c;图像中任何一个点非黑即白&#xff0c;要么为白色&#xff08;像素 为 255&#xff09;&#xff0c;要么为黑色&#x…