如果使用node从0到1开发自己的后台,node搭建本地文件服务器

2,187 阅读6分钟

这是我参与11月更文挑战的第3天,活动详情查看:2021最后一次更文挑战

image.png

    身为一个前端,工作的时候避免不了和后端对接口,看着后端一副’你不懂‘的样子,总希望自己能够自己写套接口怼到他的脸上。

    当然了,这篇文章只是入门,你还需要卧薪尝胆,秣马厉兵一番


    前后端分离技术是现如今开发的主流开发方式, 所以现在很多前端可能不是很了解后台, 知道的可能就是如何和接口去做交互,那么在这篇博客里,我们就来看看,使用我们的nodeJS怎样来写后台服务

通过小案例进行说明哈,首先项目的层级结构如下:

image.png

  • db中写的是对数据库进行的操作
  • customer是customer这个模块的对数据库的操作代码
  • pool是连接池,创建连接对象
  • router中写的是路由,可以根据路径做不同的操作,此处使用的是express中的路由.写完直接导出,后面使用的话直接导入,并且应用上就可以了
  • index是主文件,主要是创建服务器对象,启动服务器等
  • package是配置文件

1.首先我们来看db底下的pool文件,代码如下:

const mysql = require('mysql')
 
// 创建连接池对象
const pool = mysql.createPool({
    host:'127.0.0.1',
    port:3306,
    user:'root',
    password:'root',
    database:'test'
})
 
// 把连接池对象进行导出
module.exports = {
    pool
}

先安装mysql模块,然后将其进行导入

接着创建链接池对象,用于连接数据库

  • host:主机名
  • port:端口号
  • user:用户名
  • password:密码
  • database:数据库 最后将链接池对象进行导出

2. db文件夹下customer文件,代码如下:

// 封装方法
// 导入连接池对象
const {pool} = require('./pool')
 
// 查询
let findAll = (handle)=>{
    // 获取连接对象,第二个参数代表连接对象
    pool.getConnection((err,connection)=>{
        if(err) throw err;
        let sql = 'select * from account_customer'
        connection.query(sql,[],(err,result)=>{
            if(err) throw err;
            handle(result)
            // 释放连接对象到连接池
            connection.release()
        })
    })
}
// 根据顾客名字模糊查询
 
// 批量删除
 
// 通过id获取顾客信息
let findById = (handle,id)=>{
    pool.getConnection((err,connection)=>{
        if(err) throw err;
        let sql = 'select * from account_customer where id=?'
        connection.query(sql,[id],(err,result)=>{
            if(err) throw err;
            handle(result)
            connection.release()
        })
    })
}
 
// 通过id删除顾客信息
let deleteById = (handle,id)=>{
    pool.getConnection((err,connection)=>{
        if(err) throw err;
        let sql = 'delete from account_customer where id=?'
        connection.query(sql,[id],(err,result)=>{
            if(err) throw err;
            handle(result)
            connection.release()
        })
    })
}
 
 
// 保存或者更新顾客信息
let saveOrUpdate = (handle,obj)=>{
    pool.getConnection((err,connection)=>{
        if(err) throw err;
        let sql = ''
        // 更新的时候需要id
        if(obj.id){
            // 若有id存在,那么是更新
            sql = 'update account_customer set description=?,money=?,type=? where id=?'
        }else{
            // 保存sql
            sql = 'insert into account_customer(description,money,type) values(?,?,?)'
        }
 
        connection.query(sql,[obj.description,obj.money,obj.type,obj.id],(err,result)=>{
            if(err) throw err;
            handle(result)
            connection.release()
        })
    })
}
 
module.exports = {
    findAll,
    findById,
    deleteById,
    saveOrUpdate
}

代码中注释写的很清楚了,这里就不做详细的说明了,有什么不明白的,都可以私信小编哦。简单的说,其实就是去执行sql语句的,增删改查而已,如果没有sql基础,那可以先去了解下基本的sql语句哦

 

3.然后再看下router中的customer文件,代码如下:

const express = require('express')
let customerDB = require('../db/customer')
// 创建路由
let customer = express.Router()
 
// 设置路由,不同的接口实现不同的功能
// 查询所有顾客信息
customer.get('/findAll',(req,res)=>{
    // 调用dao层的方法,访问数据库
    customerDB.findAll((result)=>{
        res.send(result)
    })
})
 
customer.get('/findById',(req,res)=>{
    customerDB.findById((result)=>{
        res.send(result)
    },req.query.id)
})
 
customer.get('/deleteById',(req,res)=>{
    customerDB.deleteById((result)=>{
        res.send(result)
    },req.query.id)
})
 
customer.post('/saveOrUpdate',(req,res)=>{
    // console.log(req.body)
    customerDB.saveOrUpdate((result)=>{
        res.send('保存成功')
    },req.body)
})
 
module.exports = customer

这里主要是对路径进行过滤,根据不同的路径来调用不同的方法,从而执行不同的sql,查询到数据后,再返回到页面上.这样就实现了,请求接口,然后相应数据啦。接口和sql是一一对应的关系哦,此处的路由,进行了导出,后面在inde.js中需要使用.

 

3.再看下index.js文件,代码如下:

const express = require('express')
const bodyParser = require('body-parser')
 
// 路由对象
const customer = require('./router/customer')
 
// let customer = express.Router()
// 创建应用
let app = express()
 
app.use(bodyParser.urlencoded({extended:true}))
 
// 使用拦截器
app.all('*',(req,res,next)=>{
    res.set({
        "Access-Control-Allow-Origin":"*",
        "Content-Type":"text/plain;charset=utf-8"
    })
    next()
})
 
// 使用导进来的路由对象
app.use(customer)
 
// 启动服务器,设置端口
app.listen(3000,()=>{
    console.log('3000端口启动......')
})

在index文件中要导入路由对象,并且要使用app.use来使用导入的路由对象 拦截器里面指明了识别的编码方式,以及解决了跨域问题,* 代表所有域发起的请求都可以通过,若是你只想配置个别域可以访问,那么这里其实就相当于设置个白名单啦,只需要用域名替换*就可以啦

4.最后看下package.json中的配置,看看要安装哪些依赖

image.png

一直想尝试使用node搭建个文件服务器,接着我们继续看哈

首先,我们在做文件上传的时候,很多时候会使用到文件服务器. 从前端来说的话, 我们把数据上传到文件服务器上,然后文件服务器返回给我们一个你所上传文件的一个访问地址

也就是说文件服务器首先要读取到我们前端所上传的数据,接着,需要把文件存放到服务器的指定目录下,最后把存储地址存入数据库并返回给前台

了解了原理之后,做起来思路就比较明确了

准备工作

1.需要保证拥有node环境

  1. 创建一个文件夹node(任意名字),再文件夹下创建一个文件 serve.js(服务器文件)和index.html(前端测试文件),还有uploads文件夹(用于存储前端上传的文件夹)

  2. 在node文件夹下打开控制台,执行 npm init ,执行完成之后会生成一个package.json文件,即配置文件

首先看下server文件的完善

具体代码如下所示, 注释的很详细哦

// 要使用npm install 安装express和formidable 
// 要保证和当前文件夹同级,拥有uploads文件夹
var Express = require('express');
var App = Express();
var Path = require('path');
var Formidable = require('formidable');
var FS = require('fs');
 
App.all('*',function (req, res, next) {
  // 解决跨域
  res.header('Access-Control-Allow-Origin', '*');
  // 设置相应头数据
  res.header('Access-Control-Allow-Headers', 'Content-Type, Content-Length, Authorization, Accept, X-Requested-With , yourHeaderFeild');
  // 设置接收的方法
  res.header('Access-Control-Allow-Methods', 'PUT, POST, GET, DELETE, OPTIONS');
  next();
});
 
App.post('/upload', function(req, res){
  // 创建一个表单对象
    var form = new Formidable.IncomingForm();
    //  开启该功能,当调用form.parse()方法时,回调函数的files参数将会是一个file数组,数组每一个成员是一个File对象,此功能需要 html5中multiple特性支持。
    form.multiples = true;
    // 设置当前上传的文件存储到,当前文件的/uploads文件夹下
    form.uploadDir = Path.join(__dirname, '/uploads');
    var dirUrl
    // 监听上传的文件数据
    form.on('file', function(field, file) {
        var newName = file.name;
        // 重命名
        FS.rename(file.path, Path.join(form.uploadDir,newName),function(err) {
            if(err){
                throw err;
            }
        });
        // 得到当前上传文件的存储路径
        dirUrl = Path.join(form.uploadDir,newName)
    });
    // 监听报错
    form.on('error', function(err) {
        console.log('An error: \n' + err);
    });
    // 当接受数据完成时,将当前上传的文件的目录返回给前台
    form.on('end', function() {
        res.send(dirUrl);
    });
    // 解析请求中携带的数据
    form.parse(req);
  });
 
  // 启动服务设置端口
  var server = App.listen(1000, function(){
      console.log('Files Server listening on port 1000');
  })
前端的测试代码

   我这里是使用了vue,这个无所谓,仅供参考,你自己写原生的也可以测试哈

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
  <script src="https://cdn.bootcdn.net/ajax/libs/vue/2.6.9/vue.js"></script>
  <!-- 引入样式 -->
<link rel="stylesheet" href="https://unpkg.com/element-ui/lib/theme-chalk/index.css">
<!-- 引入组件库 -->
<script src="https://unpkg.com/element-ui/lib/index.js"></script>
</head>
<body>
   <div id="main">
    <el-upload
    class="upload-demo"
    action="http://localhost:1000/upload"
  >
    <el-button size="small" type="primary">点击上传</el-button>
  </el-upload>
   </div>
   <script>
     new Vue({
       el:'#main',
       data:{}
     })
   </script>
</body>
</html>

结合上面的代码,就是搭建一个本地文件服务器了,当然了,我是直接一次性的返回了你所上传的文件的路径,而并没有将其路径存入数据库中

这步比较简单了,毕竟路径都拿到了,而且上面已经有说明啦

前端小菜鸟,希望可以批评指正,共同学习,进步哈