【Nodejs】基于node http模块的博客demo代码实现

news2024/11/26 12:52:36

目录

package.json

www.js

db.js

app.js

routes/blog.js

controllers/blog.js

mysql.js

responseModel.js


无开发,不安全。

这个demo项目实现了用Promise异步处理http的GET和POST请求,通过mysql的api实现了博客增删改查功能,但因没有写登录身份认证功能,所以限制具体博客增删时的权限就用了假数据。

下面直接贴出源码:

package.json

{
  "name": "nodetest",
  "version": "1.0.0",
  "description": "",
  "main": "bin/www.js",
  "scripts": {
    "dev": "nodemon bin/www.js"
  },
  "keywords": [],
  "author": "",
  "license": "ISC",
  "devDependencies": {
    "nodemon": "^3.0.2"
  },
  "dependencies": {
    "mysql": "^2.18.1"
  }
}

这里用的是nodemon监视文件系统的更改,并自动重启 Node.js 应用程序

运行:npm run dev

www.js

//创建服务器
const http=require('http');
const serverHandler=require('../app');
const PORT =5000;
const server=http.createServer(serverHandler);

server.listen(PORT,()=>
{
    console.log('server running at port 5000...');
})

db.js

let MYSQL_CONFIG={};

MYSQL_CONFIG={
    host:'localhost',
    user:'root',
    password:'root',
    port:3306,
    database:'nodeblog'
}

module.exports={
    MYSQL_CONFIG
}

app.js

//业务逻辑代码
const querystring = require('querystring');
const handleBlogRoute=require('./src/routes/blog');

//处理POST数据
const getPostData=(req)=>{
    const promise=new Promise((resolve,reject)=>{
        if(req.method!=='POST'){
            resolve({});
            return;
        }

        if(req.headers['content-type']!=='application/json'){
            resolve({});
            return;
        }

        let postData='';

        req.on('data',(chunk)=>{
            postData+=chunk.toString();
        });

        req.on('end',()=>{
            if(!postData){
                resolve({});
                return;
            }
            resolve(
                JSON.parse(postData)
            );
        });
    });
    return promise;
}
const serverHandler=(req,res)=>
{
    //设置相应格式
    res.setHeader('Content-Type','application/json');

    //获取path
    const url=req.url;
    req.path=url.split('?')[0];

    //解析query
    req.query=querystring.parse(url.split('?')[1]);
    //处理POST数据
    getPostData(req).then((postData)=>{
        req.body=postData;
        //博客相关的路由
        const blogDataPromise=handleBlogRoute(req,res);
        if (blogDataPromise){
            blogDataPromise.then((blogData)=>{
                res.end(
                    JSON.stringify(blogData)
                    );
            });
            return;
        }
        //未匹配到任何路由
        res.writeHead(404,{'Content-Type':'text/plain'});
        res.write('404 Not Found');
        res.end();
    });
    
}

module.exports=serverHandler;

routes/blog.js

//处理博客相关的路由
const {SuccessModel, ErrorModel}=require('../model/responseModel');
const {getList,getDetail,createNewBlog,updateBlog,deleteBlog} = require('../controllers/blog');


const handleBlogRoute=(req,res)=>
{
    const method=req.method;
    const blogData=req.body;
    const id=req.query.id;
    if(method==='GET' && req.path==='/api/blog/list'){
        
        const author=req.query.author||'';
        const keyword=req.query.keyword||'';
        const listDataPromise=getList(author,keyword);
        return listDataPromise.then((listData)=>{
            return new SuccessModel(listData);
        });
    }

    if(method==='GET' && req.path==='/api/blog/detail'){
        const detailDataPromise=getDetail(id);
        return detailDataPromise.then(detailData=>{
            return new SuccessModel(detailData);
        })
    }

    if(method==='POST' && req.path==='/api/blog/new'){
        const author='Hacker';
        req.body.author=author;
        const newBlogDataPromise=createNewBlog(blogData);
        
        return newBlogDataPromise.then(newBlogData=>{
            return new SuccessModel(newBlogData);
        });
    }

    if(method==='POST' && req.path==='/api/blog/update'){
        const updatedBlogDataPromise=updateBlog(id,blogData);

        return updatedBlogDataPromise.then((updatedBlogData)=>{
            if (updatedBlogData){
                return new SuccessModel('更新博客成功!');
            }else{
                return new ErrorModel('更新博客失败...');
            }
        });
    }

    if(method==='POST' && req.path==='/api/blog/delete'){
        const author='Hacker';
        const deleteBlogDataPromise=deleteBlog(id,author);
       
        return deleteBlogDataPromise.then((deleteBlogData)=>{
            if (deleteBlogData){
                return  new SuccessModel('删除博客成功!');
            }else{
                return new ErrorModel('删除博客失败...');
            }
        });
    }

}

module.exports=handleBlogRoute;

controllers/blog.js

const {execSQL}=require('../db/mysql');

//获取博客列表
const getList=(author,keyword)=>{
    let sql=`select * from blogs where`;
    if(author){
        sql+=` author='${author}' `;
    }

    if(keyword){
        sql+=`and title like '%${keyword}%'`;
    }
    return execSQL(sql);
}

//获取博客详情
const getDetail=(id)=>{
    const sql=`select * from blogs where id='${id}'`;

    return execSQL(sql).then(rows=>{
        console.log('rows',rows);
        return rows[0];
    });
}

//创建新的博客
const createNewBlog=(blogData={})=>{
    const title=blogData.title;
    const content=blogData.content;
    const author=blogData.author;
    const createdAt=Date.now();

    const sql=`insert into blogs (title,content,author,createdAt) values ('${title}','${content}','${author}',${createdAt})`;

    return execSQL(sql).then(insertedResult=>{
        console.log('insertedResult',insertedResult);
        return {
            id:insertedResult.insertId
        }
    });
    
}

const updateBlog=(id,blogData={})=>{
   const title=blogData.title;
   const content=blogData.title;

   const sql=`update blogs set title='${title}', content='${content}' where id=${id}`;

   return execSQL(sql).then(updateResult=>{
    console.log('updateResult',updateResult);
    if(updateResult.affectedRows>0){
        return true;
    }
    return false;
   })
}

const deleteBlog=(id,author)=>{
    const sql=`delete from blogs where id=${id} and author='${author}'`;
    
    return execSQL(sql).then(deleteResult=>{
        console.log('deleteResult',deleteResult);
        if(deleteResult.affectedRows>0){
            return true;
        }
        return false;
    })
}
module.exports={
    getList,
    getDetail,
    createNewBlog,
    updateBlog,
    deleteBlog
}

mysql.js

const mysql=require('mysql');
const { MYSQL_CONFIG } = require('../config/db');

const connection=mysql.createConnection( MYSQL_CONFIG);

//开始连接
connection.connect();

//执行sql语句
function execSQL(sql){
   const promise=new Promise((resolve,reject)=>{
    connection.query(sql,(err,result)=>{
        if(err){
            reject(err);
            return;
        }
        resolve(result);
    })
})
   return promise;
}

module.exports={
    execSQL
}

responseModel.js

class BaseModel{
    constructor(data,message){
        if(typeof data==='string'){
            this.message=data;
            data=null;
            message=null;
        }

        if(data){
            this.data=data;
        }

        if(message){
            this.message=message;
        }
    }
}

class SuccessModel extends BaseModel{
    constructor(data,message){
        super(data,message);
        this.errno=0;
    }
}

class ErrorModel extends BaseModel{
    constructor(data,message){
        super(data,message);
        this.errno=-1;
    }
}

module.exports = {
    SuccessModel,
    ErrorModel
}

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

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

相关文章

YOLOv8改进 | 2023检测头篇 | 利用AFPN增加小目标检测层(让小目标无所遁形)

一、本文介绍 本文给大家带来的改进机制是利用今年新推出的AFPN(渐近特征金字塔网络)来优化检测头,AFPN的核心思想是通过引入一种渐近的特征融合策略,将底层、高层和顶层的特征逐渐整合到目标检测过程中。这种渐近融合方式有助于减小不同层次特征之间的语义差距,提高特征…

花了一小时,拿python手搓了一个考研背单词软件

听说没有好用的电脑端背单词软件?只好麻烦一下,花了一小时,拿python手搓了一个考研背单词软件。 代码已经开源在我的github上,欢迎大家STAR! 其中,数据是存放在sqlite中,形近词跳转是根据jaro …

【ZYNQ实验】第一篇、ZYNQ驱动HDMI显示图片

目录 第一部分、实验说明 1、点名过来看 2、实验说明 2.1、涉及到的知识 2.2、使用的硬件 3、测试效果 3.1、实验一效果 3.2、实验二效果 4、写在前面 5、参考文献 第二部分、硬件搭建 第三部分、实现方法 1、实验一 1.1、实验一原理图 1.2、MATLAB图片转换代码…

了解一下InternLM1

InternLM 是在过万亿 token 数据上训练的多语千亿参数基座模型。通过多阶段的渐进式训练,InternLM 基座模型具有较高的知识水平,在中英文阅读理解、推理任务等需要较强思维能力的场景下性能优秀,在多种面向人类设计的综合性考试中表现突出。在…

flutter项目用vscode打包apk包,完美运行到手机上

1.创建密钥库 执行以下命令: keytool -genkey -v -keystore F:/key.jks -keyalg RSA -keysize 2048 -validity 10000 -alias key 生成 2,048 位RSA密钥对和自签名证书 (SHA256withRSA) (有效期为 10,000 天) 2.填写密钥内容 执行以上命令后会提示一次输入密钥库密码、确认…

JVS规则引擎和智能BI(自助式数据分析)1.3新增功能说明

规则引擎更新功能 新增: 1、数据源新增Excel数据源; Excel数据源功能允许用户将Excel文件作为数据源导入,并进行数据清洗、转换和处理,以实现数据的集成、可视化和深度分析,为决策提供强大支持,同时保持良好的交互性…

TTPLA:一种用于输电杆塔和输电线路检测与分割的航空影像数据集

从航空图像中准确检测和分割输电塔(TTs)和电力线(PLs)对于保护电网安全和低空无人机安全起着关键作用。同时,TTs和PLs的航空图像对从事对象检测和分割工作的计算机视觉研究人员提出了许多新挑战——电力线长而细&#…

USB 转 TTL线直接读取DS18B20

简介 使用USB转TTL线直接读取DS18B20 温度。 电路图 绘制图 实物图 软件 Download 1-Wire/iButton Drivers for Windows 操作 所有的线路连接好之后将 USB 转 TTL线接到PC上; 安装软件 Download 1-Wire/iButton Drivers for Windows 并打开 软件打开之后先选择串口后 …

VitePress搭建Vite官方中文文档首页

✨专栏介绍 在当今数字化时代,Web应用程序已经成为了人们生活和工作中不可或缺的一部分。而要构建出令人印象深刻且功能强大的Web应用程序,就需要掌握一系列前端技术。前端技术涵盖了HTML、CSS和JavaScript等核心技术,以及各种框架、库和工具…

记一次使用mpvue开发微信小程序动画播放播放完成再播放下一个动画,实现动画队列的实战操作

微信小程序wxss支持Css的keyframes动画,我们想通过事件监听,在动画开始、动画播放阶段、动画播放结束的时候进行下一步动作。如下图,有一个从右飘入,然后从左侧出去的动画,我们希望的是,前一个出去后&#…

pytorch07:损失函数与优化器

目录 一、损失函数是什么二、常见的损失函数2.1 nn.CrossEntropyLoss交叉熵损失函数2.1.1 交叉熵的概念2.2.2 交叉熵代码实现2.2.3 加权重损失 2.2 nn.NLLLoss2.2.1 代码实现 2.3 nn.BCELoss2.3.1 代码实现 2.4 nn.BCEWithLogitsLoss2.4.1 代码实现 三、优化器Optimizer3.1 什么…

GPT/GPT4科研应用与AI绘图技术及论文高效写作(建议收藏)

详情点击链接:GPT/GPT4科研实践应用与AI绘图技术及论文高效写作 一OpenAI 1.最新大模型GPT-4 Turbo 2.最新发布的高级数据分析,AI画图,图像识别,文档API 3.GPT Store 4.从0到1创建自己的GPT应用 5. 模型Gemini以及大模型Clau…

轻量检测模型NanoDet解析

官方解读:YOLO之外的另一选择,手机端97FPS的Anchor-Free目标检测模型NanoDet现已开源~ - 知乎 official implementation: GitHub - RangiLyu/nanodet: NanoDet-Plus⚡Super fast and lightweight anchor-free object detection model. &…

[LitCTF 2023]这是什么?SQL !注一下 !

[LitCTF 2023]这是什么?SQL !注一下 ! wp 题目描述:为了安全起见多带了几个套罢了o(▽)q 页面内容(往下滑): SQL 语句已给出,无非是更换了闭合方式。 先输个 1 试试: …

<HarmonyOS第一课>1~10课后习题汇总

HarmonyOS第一课 <HarmonyOS主题课>1~3课后习题汇总 1运行Hello World 判断题 main_pages.json存放页面page路径配置信息。(正确)DevEco Studio是开发HarmonyOS应用的一站式集成开发环境。(正确) 单选题…

MS4553S用于开漏模式和推拉模式的 2bit 双向电平转换器,可替代TXS0102/PCA9306等

产品简述 MS4553S 是一款双向电平转换器,可以用作混合电压的数字信 号系统中。其使用两个独立构架的电源供电, A 端供电电压范围是 1.65V 到 5.5V , B 端供电电压范围是 2.3V 到 5.5V 。可用在电压为 1.8V 、 2.5V 、 3.3V 和 5V 的信号转…

vue3 vuedraggable draggable element must have an item slot

vue3vite 看官网使用这种<template #item“{ element }”> <draggablev-model"myArray"start"onStart"end"onEnd":sort"false"item-key"id"draggable".item"handle".mover" ><template…

3-sql注入之Mysql手工注入

文章目录 sql注入之Mysql手工注入sqli-labs数字型注入注入流程注入语句 sql注入之Mysql手工注入 练习靶场为sqli-labs第二关数字型注入 sqli-labs数字型注入 在url中输入id值&#xff0c;执行查询sql语句。即可得到对应数据 less-2源码分析&#xff1a; 浏览器 进行数据提交…

python旅游大数据分析可视化大屏 游客分析+商家分析+舆情分析 计算机毕业设计(附源码)Flask框架✅

毕业设计&#xff1a;2023-2024年计算机专业毕业设计选题汇总&#xff08;建议收藏&#xff09; 毕业设计&#xff1a;2023-2024年最新最全计算机专业毕设选题推荐汇总 &#x1f345;感兴趣的可以先收藏起来&#xff0c;点赞、关注不迷路&#xff0c;大家在毕设选题&#xff…

关于目标检测任务中,XML(voc格式)标注文件的可视化

1. 前言 最近在弄关于目标检测的任务&#xff0c;因为检测的图片和标签是分开的&#xff0c;可视化效果不明显&#xff0c;也不知道随便下载的数据集&#xff0c;标注信息对不对。网上看了好多代码&#xff0c;代码风格和本人平时不同&#xff0c;看起来麻烦&#xff0c;也不知…