1200字范文,内容丰富有趣,写作的好帮手!
1200字范文 > NodeJS之搭建Web服务器

NodeJS之搭建Web服务器

时间:2023-03-15 21:13:59

相关推荐

NodeJS之搭建Web服务器

文章目录

认识NodeJS认识HTTP请求处理get请求处理post请求处理http请求总结博客项目实战搭建开发环境初始化路由开发第一个路由处理异步代码读取文件的例子处理POST数据 开发新建、更新、删除博客的路由新建路由 使用MySQLNodeJS连接MySQL封装执行sql语句的工具函数获取博客列表接口对接MySQL博客详情、新建博客接口对接MySQL更新博客、删除博客接口对接MySQL

⭐️学习视频教程来自 B站

✨笔记源码——点击下载

认识NodeJS

javascript可以运行在浏览器上,因为google浏览器内置V8引擎

NodeJS是基于V8引擎的一个容器,又是C++编写的 所以JS代码也可以运行在NodeJS中

认识HTTP请求

DNS解析,建立TCP连接,然后发起HTTP请求服务端接收到HTTP请求,进行处理,返回数据客户端接收到返回的数据,处理数据(例如渲染页面)

nodejs用url替换querystring

谷歌json格式美化插件:蓝奏云 密码:63mj

处理get请求

const http = require("http");const url = require("url");const server = http.createServer((req, res) => {const method = req.method;console.log("method", method);let reqUrl = req.url;let query = url.parse(reqUrl, true).query;res.end(JSON.stringify(query));});server.listen(5000, () => {console.log("server running at prot 5000");});

处理post请求

const http = require("http");const server = http.createServer((req, res) => {if (req.method === "POST") {let postData = "";// 流streamreq.on("data", (chunk) => {postData += chunk.toString();});req.on("end", () => {console.log("postData", postData);res.end("数据接收完毕");});console.log("post data content type", req.headers["content-type"]);}});server.listen(5000, () => {console.log("server running at prot 5000");});

处理http请求总结

const http = require("http");const url = require("url");const server = http.createServer((req, res) => {const method = req.method;const reqUrl = req.url;const path = reqUrl.split("?")[0];const query = url.parse(reqUrl, true).query;const responseData = {method,reqUrl,path,query,};res.setHeader("Content-Type", "application/json");if (method === "GET") {res.end(JSON.stringify(responseData));}if (method === "POST") {let postData = "";req.on("data", (chunk) => {postData += chunk.toString();});req.on("end", () => {responseData.postData = postData;res.end(JSON.stringify(responseData));});}});server.listen(5000, () => {console.log("server running at prot 5000");});

博客项目实战

搭建开发环境

npm init -y

npm install nodemon -D --registry=https://registry.

bin/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 prot 5000");});

app.js

const serverHandler = (req, res) => {res.setHeader("Content-Type", "application/json");const responseData = {name: "nodeJS学习",age: 21,};res.end(JSON.stringify(responseData));};module.exports = serverHandler;

初始化路由

src/routes/blog.js

// 处理博客相关的路由const handleBlogRoute = (req, res) => {// 定义处理路由的逻辑const method = req.method;if (method === "GET" && req.path === "/api/blog/list") {return {message: "获取博客列表的接口",};}if (method === "GET" && req.path === "/api/blog/detail") {return {message: "获取博客详情的接口",};}if (method === "POST" && req.path === "/api/blog/new") {return {message: "新建博客接口",};}if (method === "POST" && req.path === "/api/blog/update") {return {message: "更新博客接口",};}if (method === "POST" && req.path === "/api/blog/delete") {return {message: "删除博客接口",};}};module.exports = handleBlogRoute;

app.js

const handleBlogRoute = require("./src/routes/blog");const serverHandler = (req, res) => {res.setHeader("Content-Type", "application/json");const url = req.url;req.path = url.split("?")[0];const blogData = handleBlogRoute(req, res);if (blogData) {res.end(JSON.stringify(blogData));return;}res.writeHead(404, {"Content-Type": "text/plain" });res.write("404 Not Found");res.end();};module.exports = serverHandler;

开发第一个路由

想让返回的数据格式更加规范

src/model/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,};

src/controllers/blog.js

// 博客相关的方法const getList = (author, keyword) => {// 从数据库里拿数据// 先返回假数据return [{id: 1,title: "标题1",content: "内容1",author: "zhangsan",createdAt: 1667208603225,},{id: 2,title: "标题2",content: "内容2",author: "zhangsan",createdAt: 1667208603277,},];};module.exports = {getList,};

处理异步代码

把获取博客详情的接口先补充一下

post请求处理逻辑实际上是异步的

if (req.method === "POST") {let postData = "";// 流streamreq.on("data", (chunk) => {// 处理数据内容, 这里会是一个异步的过程postData += chunk.toString();});req.on("end", () => {console.log("postData", postData);res.end("数据接收完毕");});}

读取文件的例子

const fs = require("fs");const path = require("path");// 读取文件内容// function getFileContent(filename, callback) {// 数据文件的绝对路径// const fullFilename = path.resolve(__dirname, "data", filename);// fs.readFile(fullFilename, (err, data) => {//if (err) {// console.error(err);// return;//}//callback(JSON.parse(data.toString()));// });// }// 回调地狱// getFileContent("a.json", (aData) => {// console.log("aData", aData);// getFileContent(aData.next, (bData) => {//console.log("bData", bData);//getFileContent(bData.next, (cData) => {// console.log("cData", cData);//});// });// });function getFileContent(filename) {const promise = new Promise((resolve, reject) => {// 数据文件的绝对路径const fullFilename = path.resolve(__dirname, "data", filename);fs.readFile(fullFilename, (err, data) => {if (err) {reject(err);return;}resolve(JSON.parse(data.toString()));});});return promise;}getFileContent("a.json").then((aData) => {console.log("aData", aData);return getFileContent(aData.next);}).then((bData) => {console.log("bData", bData);return getFileContent(bData.next);}).then((cData) => {console.log("cData", cData);});

处理POST数据

app.js

const handleBlogRoute = require("./src/routes/blog");const url = require("url");// 处理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");// 获取pathconst reqUrl = req.url;req.path = reqUrl.split("?")[0];// 解析queryreq.query = url.parse(reqUrl, true).query;// 处理POST数据getPostData(req).then((postData) => {req.body = postData;// 博客相关的路由const blogData = handleBlogRoute(req, res);if (blogData) {res.end(JSON.stringify(blogData));return;}// 未匹配到任何路由res.writeHead(404, {"Content-Type": "text/plain" });res.write("404 Not Found");res.end();});};module.exports = serverHandler;

开发新建、更新、删除博客的路由

新建路由

src/controllers/blog.js

// 博客相关的方法const getList = (author, keyword) => {// 从数据库里拿数据// 先返回假数据return [{id: 1,title: "标题1",content: "内容1",author: "zhangsan",createdAt: 1667208603225,},{id: 2,title: "标题2",content: "内容2",author: "zhangsan",createdAt: 1667208603277,},];};const getDeatil = (id) => {// 先返回假数据return {id: 1,title: "标题1",content: "内容1",author: "zhangsan",createdAt: 1667208603225,};};// 新建博客路由const createNewBlog = (blogData) => {// blogData title contentconsole.log(blogData);return {id: 1,};};// 更新const updateBlog = (id, blogData) => {console.log("id", id);console.log("blogData", blogData);return true;};// 删除const deleteBlog = (id) => {console.log("id", id);return true;};module.exports = {getList,getDeatil,createNewBlog,updateBlog,deleteBlog,};

src/routes/blog.js

const {getList,getDeatil,createNewBlog,updateBlog,deleteBlog,} = require("../controllers/blog");const {SuccessModel, ErrorModel } = require("../model/responseModel");// 处理博客相关的路由const handleBlogRoute = (req, res) => {// 定义处理路由的逻辑const method = req.method;const id = req.query.id;const blogData = req.body;// 博客列表路由if (method === "GET" && req.path === "/api/blog/list") {// /api/blog/list?author=zhangsan&keyword=123// new SuccessModel()const author = req.query.author || "";const keyword = req.query.keyword || "";const listData = getList(author, keyword);return new SuccessModel(listData);}// 博客详情路由if (method === "GET" && req.path === "/api/blog/detail") {const detailData = getDeatil(id);return new SuccessModel(detailData);}// 新建博客路由if (method === "POST" && req.path === "/api/blog/new") {const newBlogData = createNewBlog(blogData);return new SuccessModel(newBlogData);}// 更新博客路由if (method === "POST" && req.path === "/api/blog/update") {const updateBlogData = updateBlog(id, blogData);if (updateBlogData) {return new SuccessModel("更新博客成功");} else {return new ErrorModel("更新博客失败...");}}// 删除博客路由if (method === "POST" && req.path === "/api/blog/delete") {const deleteBlogData = deleteBlog(id, blogData);if (deleteBlogData) {return new SuccessModel("删除博客成功");} else {return new ErrorModel("删除博客失败...");}}};module.exports = handleBlogRoute;

使用MySQL

use myblog;-- show tables;-- insert into blogs (title, content, author, createAt) values ('标题2', '内容2', 'zhangsan', 1234567890888)-- select * from blogs;-- select id, author from blogs;-- select count(*) as total from blogsselect * from blogs where author like '%zhang%' order by id desc;

update blogs set content="内容1" where id=1delete from blogs where title="标题2"; -- 不安全

update blogs set status='0' where author='zhangsan' -- 软删除select * from blogs where status<>0

NodeJS连接MySQL

npm i mysql

const mysql = require("mysql");// 创建连接对象const connection = mysql.createConnection({host: "localhost",user: "root",password: "IKUN1220",port: 3306,database: "myblog",});// 开始连接connection.connect();// 执行sqlconst sql = `select * from blogs`;connection.query(sql, (error, result) => {if (error) {console.error(error);return;}console.log("result", result);});// 关闭连接connection.end();

封装执行sql语句的工具函数

src/db/mysql.js

const mysql = require("mysql");const {MY_CONFIG } = require("../config/db");// 创建连接对象const connection = mysql.createConnection(MY_CONFIG);// 开始连接connection.connect();// 执行sql// function execSQL(sql, callback) {// connection.query(sql, callback);// }// promise优化 避免出现回调地狱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,};

src/config/db.js

let MY_CONFIG = {};MY_CONFIG = {host: "localhost",user: "root",password: "IKUN1220",port: 3306,database: "myblog",};module.exports = {MY_CONFIG,};

获取博客列表接口对接MySQL

博客详情、新建博客接口对接MySQL

更新博客、删除博客接口对接MySQL

// 更新const updateBlog = (id, blogData = {}) => {const title = blogData.title;const content = blogData.content;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;});};-------------------// 更新博客路由if (method === "POST" && req.path === "/api/blog/update") {const updateBlogDataPrmise = updateBlog(id, blogData);return updateBlogDataPrmise.then((updateBlogData) => {if (updateBlogData) {return new SuccessModel("更新博客成功");} else {return new ErrorModel("更新博客失败...");}});}

// 删除const deleteBlog = (id) => {const sql = `delete from blogs where id = ${id}`; //实际开发使用update进行软删除return execSQL(sql).then((deleteResult) => {if (deleteResult.affectedRows > 0) {return true;}return false;});};------// 删除博客路由if (method === "POST" && req.path === "/api/blog/delete") {const deleteBlogDataPromise = deleteBlog(id);return deleteBlogDataPromise.then((deleteBlogData) => {if (deleteBlogData) {return new SuccessModel("删除博客成功");} else {return new ErrorModel("删除博客失败...");}});}

删除还要对作者进行一个限制,只有对应的作者才能够删除

// 删除const deleteBlog = (id, author) => {const sql = `delete from blogs where id = ${id} and author = '${author}'`;return execSQL(sql).then((deleteResult) => {if (deleteResult.affectedRows > 0) {return true;}return false;});};---------------// 删除博客路由if (method === "POST" && req.path === "/api/blog/delete") {// 未写登录 暂时写死const author = "zhangsan";const deleteBlogDataPromise = deleteBlog(id, author);return deleteBlogDataPromise.then((deleteBlogData) => {if (deleteBlogData) {return new SuccessModel("删除博客成功");} else {return new ErrorModel("删除博客失败...");}});}

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。