0


快速入门 NodeJS 之『搭建Web服务器』(搭建个人博客相关)

一.搭建开发环境

1.创建一个空文件夹,在vscode中打开

2.开启package文件,因为需要用到npm包

  1. **npm init -y **

3.创建bin文件夹,也就是程序运行最开始访问的文件夹

4.www.js创建服务器

  1. //创建服务器
  2. const http = require('http');
  3. //将服务器回调函数引入
  4. const serverHandler = require('../app')
  5. //端口
  6. const PORT = 5000;
  7. const server = http.createServer(serverHandler);
  8. server.listen(PORT, () => {
  9. // 监听成功执行的回调
  10. console.log('server running at port 5000.....');
  11. })
  1. 将回调函数单独抽离出来,放在根目录文件app.js
  1. //写回到函数,将createServer中的回调函数抽离了出来,目的是更好的维护
  2. const serverHandler = (req, res) => {
  3. //这里面是服务器的业务代码
  4. //1.设置返回的数据类型
  5. res.setHeader('Content-Type', 'application/json')
  6. //2.数据格式
  7. const responseData = {
  8. name: 'alva',
  9. age: 21
  10. }
  11. res.end(
  12. JSON.stringify(responseData)
  13. )
  14. }
  15. module.exports = serverHandler;

5.启动服务器

  1. **5.1启动前,将package.json中的main属性修改成bin/www.js设置启动入口**

** 5.2安装工具 **

** npm install nodemon -D**

5.3修改

"scripts": {

** "dev": "nodemon bin/www.js"**

** },**

  1. 当服务器代码发生改变时重新运行最新的代码

** 5.4.启动服务器**

** npm run dev**

6.在浏览器输入 http://locsalhost:5000

  1. 以上开发环境就已经搭建好了

二.路由配置

1.根目录创建src下的routes文件夹,里面创建blog.js文件

  1. //处理博客相关的路由,定义处理路由的逻辑
  2. const handleBlogRoute = (req, res) => {
  3. const method = req.method;
  4. const url = req.url;
  5. const path = url.split('?')[0] //问号分割取前半段
  6. //如果请求如下就返回下面的结果,这个结果会保存到blogData
  7. if (method === 'GET' && path === '/api/blog/list') {
  8. return {
  9. message: '获取博客列表的接口'
  10. }
  11. }
  12. }
  13. module.exports = handleBlogRoute;

接着在服务器的业务代码中接收这个数据

  1. res.setHeader('Content-Type', 'application/json')
  2. //路由返回数据结果(将请求和响应传入)
  3. const blogData = handleBlogRoute(req, res)
  4. if (blogData) {
  5. //如果拿到了,就结束请求,返回一个响应
  6. res.end(
  7. )
  8. }

注意: 上面的代码中blogData是一个对象 ,但是服务器返回给浏览器的应该是字符串,所以应该进行转换

  1. if (blogData) {
  2. //如果拿到了,就结束请求,返回一个响应
  3. res.end(
  4. JSON.stringify(blogData)
  5. );
  6. //响应之后,下面的代码不再执行,所以return一下
  7. return;
  8. }
  1. **现在我们已经定义好了一个接口,就是 /api/blog/list**

我们尝试在浏览器进行访问

前端拿到这样的字符串就可以进行解析渲染到页面上

2.定义多个接口

  1. if (method === 'GET' && path === '/api/blog/detail') {
  2. return {
  3. message: '获取博客详情的接口'
  4. }
  5. }
  6. if (method === 'POST' && path === '/api/blog/new') {
  7. return {
  8. message: '新建博客的接口'
  9. }
  10. }
  11. if (method === 'POST' && path === '/api/blog/update') {
  12. return {
  13. message: '更新博客的接口'
  14. }
  15. }
  16. if (method === 'POST' && path === '/api/blog/delete') {
  17. return {
  18. message: '删除博客的接口'
  19. }
  20. }
  1. **2.2测试接口**

对于post请求的接口,由于请求体比较大,我们可以使用postman 或者apifox工具进行测试

3.处理错误请求

  1. if (blogData) {
  2. //如果拿到了,就结束请求,返回一个响应
  3. res.end(
  4. JSON.stringify(blogData)
  5. );
  6. //响应之后,下面的代码不再执行,所以return一下
  7. return;
  8. }
  9. //如果不是上面的路由,就会返回下面的结果
  10. res.writeHead(404, { 'Content-Type': 'text/plain' }); //无格式正文
  11. res.write('404 Not Found');
  12. res.end(); //终止响应

4.改造

这个handleBlogRoute只是关于博客的请求处理,如果我们还有别的路由请求需要处理可以进行如下操作

将下面的部分放到 服务器业务代码返回数据之前

  1. const url = req.url;
  2. const path = url.split('?')[0] //问号分割取前半段

放入后做改造

  1. const url = req.url;
  2. req.path = url.split('?')[0] //问号分割取前半段

在进行请求判断时,应该使用下面的写法

  1. req.path==='/api/xxx'

三.响应数据格式优化

创建src目录下面的model文件夹,里面新建一个responseModel.js

  1. class BaseModel {
  2. //构造函数
  3. constructor(data, message) {
  4. //数据可能是对象或者string,如果是string,直接message返回
  5. if (typeof data == 'string') {
  6. this.message = data
  7. data = null
  8. message = null
  9. }
  10. if (data) {
  11. this.data = data
  12. }
  13. if (message) {
  14. this.message = message
  15. }
  16. }
  17. }
  18. //根据基类,下面是成功与失败的模型
  19. class SuccessModel extends BaseModel {
  20. constructor(data, message) {
  21. super(data, message)
  22. this.errno = 0;
  23. }
  24. }
  25. class ErrorModel extends BaseModel {
  26. constructor(data, message) {
  27. super(data, message)
  28. this.errno = -1;
  29. }
  30. }
  31. module.exports = {
  32. SuccessModel,
  33. ErrorModel
  34. }

获取blog列表接口修改示例

  1. **接口:**

/api/blog/list?author = zhansan&keyword=123

1.先拿到参数

  1. req.path = url.split('?')[0] //问号分割取前半段
  2. //解析query
  3. req.query = querystring.parse(url.split('?')[1]);

2.返回数据改造

  1. //如果请求如下就返回下面的结果,这个结果会保存到blogData
  2. if (method === 'GET' && req.path === '/api/blog/list') {
  3. const author = req.query.author || '';
  4. const keyword = req.query.keyword || '';
  5. const listData = getList(author, keyword); //根据参数获取数据
  6. return new SuccessModel(listData)
  7. // return {
  8. // message: '获取博客列表的接口'
  9. // }
  10. }

3.src下创建controller包,新建一个blog.js文件

  1. //博客相关的方法
  2. const getList = (author, keyword) => {
  3. //从数据库里面拿数据
  4. //先做假数据
  5. return [{
  6. id: 1,
  7. title: '标题一',
  8. content: '内容一',
  9. author: '张三',
  10. createAt: 161055518935 //date.now()获取的时间戳
  11. },
  12. {
  13. id: 2,
  14. title: '标题二',
  15. content: '内容二',
  16. author: '李四',
  17. createAt: 161055535044 //date.now()获取的时间戳
  18. }
  19. ]
  20. }
  21. module.exports = {
  22. getList
  23. }

4.测试

四.异步处理post请求数据

  1. const querystring = require('querystring')
  2. const handleBlogRoute = require('./src/routes/blog')
  3. //处理post数据
  4. const getPostData = (req) => {
  5. const promise = new Promise((resolve, reject) => {
  6. if (req.method !== 'POST') {
  7. resolve({})
  8. return;
  9. }
  10. if (req.headers['content-type'] !== 'application/json') {
  11. resolve({})
  12. return;
  13. }
  14. let postData = ''
  15. //返回的是数据段
  16. req.on('data', (chunk) => {
  17. postData += chunk.toString();
  18. })
  19. req.on('end', () => {
  20. if (!postData) {
  21. resolve({})
  22. return;
  23. }
  24. resolve(JSON.parse(postData))
  25. })
  26. })
  27. return promise;
  28. }
  29. //这里面是服务器的业务代码
  30. const serverHandler = (req, res) => {
  31. //设置返回的数据类型(响应格式)
  32. res.setHeader('Content-Type', 'application/json')
  33. //获取path
  34. const url = req.url;
  35. req.path = url.split('?')[0] //问号分割取前半段
  36. //解析query
  37. req.query = querystring.parse(url.split('?')[1]);
  38. //下面的函数返回的是一个promise,这是一个异步的过程,意思是这个还没走完代码就会往下执行别的步骤,
  39. //这样可能会导致有些路由访问不到,因为数据还没处理完
  40. getPostData(req).then(
  41. (postData) => {
  42. req.body = postData
  43. //路由返回数据结果(将请求和响应传入)
  44. const blogData = handleBlogRoute(req, res)
  45. if (blogData) {
  46. //如果拿到了,就结束请求,返回一个响应
  47. res.end(
  48. JSON.stringify(blogData)
  49. );
  50. //响应之后,下面的代码不再执行,所以return一下
  51. return;
  52. }
  53. //如果不是上面的路由,就会返回下面的结果
  54. res.writeHead(404, { 'Content-Type': 'text/plain' }); //无格式正文
  55. res.write('404 Not Found');
  56. res.end(); //终止响应
  57. }
  58. )
  59. }
  60. module.exports = serverHandler;
  61. module.exports = serverHandler;
  1. **例如更新博客的路由**
  1. const handleBlogRoute = (req, res) => {
  2. const id = req.query.id
  3. const blogData = req.body
  4. const method = req.method;
  5. //如果请求如下就返回下面的结果,这个结果会保存到blogData
  6. if (method === 'POST' && req.path === '/api/blog/update') {
  7. const updatedBlogData = updatedBlog(blogData)
  8. if (updatedBlogData) {
  9. return new SuccessModel('更新博客成功')
  10. }
  11. // return {
  12. // message: '更新博客的接口'
  13. // }
  14. }
  15. }

上面的操作中,因为许多接口请求时都用到了id和数据,所以将它们提取出来

  1. **方法**
  1. //更新博客 blogData = {}是设置空对象,防止没有传
  2. const updatedBlog = (id, blogData = {}) => {
  3. console.log('id', id);
  4. console.log('blogData', blogData);
  5. return true
  6. }

五.使用MySQL

1.在数据库中新建一个数据库,并创建blogs表

2.nodejs连接mysql-一个测试demo

1.创建index.js

2.终端进入mysql-demo

** npm init -y**

** npm install mysql**

3.index.js实现连接数据库

  1. const mysql = require('mysql')
  2. //创建连接对象
  3. const connection = mysql.createConnection({
  4. host: 'localhost',
  5. user: 'root',
  6. password: '123456',
  7. 'port': 3306,
  8. database: 'myblog'
  9. })
  10. //开始连接
  11. connection.connect();
  12. //执行sql语句
  13. const sql = `select * from blogs`
  14. connection.query(sql, (err, result) => {
  15. if (err) {
  16. console.error('error', err)
  17. return;
  18. }
  19. console.log('result', result);
  20. })
  21. //关闭连接
  22. connection.end()

** 4.终端输入node index.js**

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

  1. **src下面创建db文件夹,新建mysql.js文件**

** 终端输入 **

  1. PS E:\node> **npm install mysql**
  2. **mysql.js**
  1. const mysql = require('mysql')
  2. //创建连接对象
  3. const connection = mysql.createConnection({
  4. host: 'localhost',
  5. user: 'root',
  6. password: '123456',
  7. 'port': 3306,
  8. database: 'myblog'
  9. })
  10. //开始连接
  11. connection.connect();
  12. //执行sql语句的函数
  13. function execSQL(sql) {
  14. const promise = new Promise((resolve, reject) => {
  15. connection.query(sql, (err, result) => {
  16. if (err) {
  17. reject(err)
  18. return;
  19. }
  20. resolve(result)
  21. })
  22. })
  23. return promise;
  24. }
  25. module.exports = {
  26. execSQL
  27. }

测试获取列表接口

  1. if (method === 'GET' && req.path === '/api/blog/list') {
  2. const sql = `select * from blogs`
  3. execSQL(sql).then(result => {
  4. console.log(result);
  5. })
  6. const author = req.query.author || '';
  7. const keyword = req.query.keyword || '';
  8. const listData = getList(author, keyword); //根据参数获取数据
  9. return new SuccessModel(listData)
  10. // return {
  11. // message: '获取博客列表的接口'
  12. // }
  13. }

访问路由,控制台输出

完善请求接口

  1. const handleBlogRoute = (req, res) => {
  2. const id = req.query.id
  3. const blogData = req.body
  4. const method = req.method;
  5. //如果请求如下就返回下面的结果,这个结果会保存到blogData
  6. if (method === 'GET' && req.path === '/api/blog/list') {
  7. const author = req.query.author || '';
  8. const keyword = req.query.keyword || '';
  9. const listData = getList(author, keyword); //根据参数获取数据,这里返回的是一个promise对象
  10. return listData.then(listData => {
  11. return new SuccessModel(listData)
  12. })
  13. }
  1. //博客相关的方法
  2. const getList = (author, keyword) => {
  3. //从数据库里面拿数据(根据用户以及关键字)
  4. //由于我们要做拼接,改成let
  5. let sql = `select * from blogs where`
  6. if (author) {
  7. sql += ` author = '${author}' `
  8. }
  9. if (keyword) {
  10. sql += `and title like '%${keyword}%' ` //模糊查询
  11. }
  12. return execSQL(sql)
  13. }

接下来在app.js文件中使用了handleBlogRoute的地方修改返回结果代码

  1. req.body = postData
  2. //路由返回数据结果(将请求和响应传入)
  3. const blogData = handleBlogRoute(req, res)
  4. if (blogData) {
  5. //这是一个promise对象
  6. blogData.then(blogData => {
  7. //如果拿到了,就结束请求,返回一个响应
  8. res.end(
  9. JSON.stringify(blogData)
  10. );
  11. })
  12. //响应之后,下面的代码不再执行,所以return一下
  13. return;
  14. }

注意 如果我们没有输入参数,会报错,因为我们的sql语句中where后面没有内容,语句错误,为避免这样的问题,我们可以进行下面的小技巧

  1. let sql = `select * from blogs where 1=1`


本文转载自: https://blog.csdn.net/m0_58467275/article/details/129465063
版权归原作者 亦菲小机灵 所有, 如有侵权,请联系我们删除。

“快速入门 NodeJS 之『搭建Web服务器』(搭建个人博客相关)”的评论:

还没有评论