Nodejs + Express + MongoDB combate real

Instalación del proyecto
  1. Instale andamios rápidos:npm install express-generator -g
  2. Crear un proyecto: express -e project-e representa el uso de la plantilla ejs, proyecto es el nombre del proyecto
  3. Ingrese al proyecto: npm installdescargue el paquete de dependencia
  4. Instale nodemon: npm install nodemon -guse nodemon para iniciar el proyecto, no node para comenzar
    Inserte la descripción de la imagen aquí
  5. Proyecto de inicio:, npm startEl número de puerto se puede ver en el archivo de inicio www.
El proyecto se conecta a la base de datos MongoDB
  1. Instale mongodb integrado con nodejs:npm install mongodb -S

  2. Cree un archivo de modelo en el proyecto, cree index.js a continuación, y todo el código conectado a la base de datos se encapsula en este archivo

     const MongoClient = require('mongodb').MongoClient;  // 创建Mongo的客户端对象
     const url = 'mongodb://localhost:27017';  // 连接数据库url
     const dbName = 'project';   // 连接的数据库名字
     // 数据库的连接方法封装
     function connect(callback){
         // 使用connect方法连接到服务器
         // err:错误对象。client:客户端连接成功的对象
         MongoClient.connect(url, function(err, client) {
             if(err){ // 如果连接错误,打印错误信息
                 console.log('数据库连接错误!',err);
             }else{  // 否则
                 const db = client.db(dbName);  // 数据库连接成功的对象
                 callback && callback(db);  // 利用回调函数处理
                 client.close();  // 每次调用成功,还要再关闭数据库
             }
         });
     }
     
     module.exports = {connect}
    
  3. Llamada: se utilizará para escribir datos en la base de datos a través del enrutamiento.

     var express = require('express');
     var router = express.Router();
     var model = require('../model');  // 引入连接数据库方法
     /* GET users listing. */
     router.get('/', function(req, res, next) {
       res.send('respond with a resource');
     });
     
     // 注册接口
     router.post('/regist',function(req, res, next){
       var data = {
         username:req.body.username,
         password:req.body.password,
         password2:req.body.password2
       }
       model.connect(function(db){
         db.collection('users').insert(data,function(err,ret){
           if(err){
             console.log('注册失败!',err);
             res.redirect('/regist');
           }else{
             res.redirect('/login');
           }
         })
       })
     })
     
     module.exports = router;
    
Sintaxis de la base de datos operativa después de que el proyecto presenta MongoDB
  1. Al registrarse, escriba los datos de registro del usuario en la base de datos

     model.connect(function(db){ // 这里的data是form表单提交过来的数据
         db.collection('users').insert(data,function(err,ret){
           if(err){
             console.log('注册失败!',err);
             res.redirect('/regist');
           }else{
             res.redirect('/login');
           }
         })
       })
    
  2. Al iniciar sesión, busque los datos correspondientes en la base de datos para ver si son coherentes con la base de datos

     model.connect(function(db){  // 连接数据库
     // 进入users库,寻找data这个数据.toArray转换成数组
     db.collection('users').find(data).toArray(function(err,docs){
       // 如果报错,重新登陆
       if(err){
         res.redirect('/login');
       }else{  
         // 否则校验数据,如果是空数组,说明没找到这个用户,让他去重新登录.找到的话.登陆成功,进入主页面
         if(docs.length > 0){
           // 登陆成功,进行session会话存储(将用户的信息进行存储)
           // 这样的话,前端每次去请求的时候,先去session里面找username,如果有值,那么证明他是登陆状态的,那么直接跳转登陆页面就好
           req.session.username = data.username;
           res.redirect('/'); // 进入主页
         }else{
           res.redirect('/login');
         }
       }
     })
    

    })

Intercepción de inicio de sesión (después de que el inicio de sesión sea exitoso, la información del usuario se guardará. En el tiempo especificado, el usuario no necesita ingresar la cuenta y contraseña al iniciar sesión nuevamente)
  1. Aquí se utiliza un módulo de herramientas: el express-sessionservidor debe guardar durante la sesión

  2. instalación:npm install express-session -S

  3. El primer paso para configurar la sesión: introducir en app.jsvar session = require('express-session');

  4. Configurar el segundo paso de la sesión: configurar el middleware de la sesión en app.js

     // session配置
     app.use(session({
       secret: 'wangrenke project', // 可以随便改的
       resave: false,
       saveUninitialized: true,
       cookie: { maxAge: 1000 * 60 * 5 }  // 在服务端使用session时,会向客户端写入cookie,所以这里要指定一个cookie的有效期(即用户登陆多久是有效的)这里是五分钟
     }))
    
  5. Uso: Cuando el usuario inicia sesión correctamente, necesitamos almacenar una sesión y almacenar al usuario en la sesión, de modo que cuando volvamos a solicitar desde el front-end, primero vayamos a la sección para obtener el nombre de usuario. Si hay un valor , significa el estado de inicio de sesión, directamente Omita la página de inicio; de lo contrario, salte a la página de inicio para iniciar sesión nuevamente

     model.connect(function(db){  // 连接数据库
         // 进入users库,寻找data这个数据.toArray转换成数组
         db.collection('users').find(data).toArray(function(err,docs){
           // 如果报错,重新登陆
           if(err){
             res.redirect('/login');
           }else{  
             // 否则校验数据,如果是空数组,说明没找到这个用户,让他去重新注册.找到的话.登陆成功,进入主页面
             if(docs.length > 0){
               // 登陆成功,进行session会话存储(将用户的信息进行存储)
               // 这样的话,前端每次去请求的时候,先去session里面找username,如果有值,那么证明他是登陆状态的,那么直接跳转登陆页面就好
               req.session.username = data.username;
               res.redirect('/'); // 进入主页
             }else{
               res.redirect('/login');
             }
           }
         })
       })
    
  6. Configurar bloqueo de inicio de sesión

     // 登录拦截(当进入系统的时候)
     app.get('*',function(req,res,next){
       var user = req.session.username;
       var path = req.path;
       console.log("session----user",user);
       // 如果是进的登录页或注册页,我们不拦截
       if(path != '/login' && path != '/regist'){
         if(!user){
           res.redirect('/login');
         }
       }
       next();
     })
    
desconectar
  1. Información clara del personal en la sesión

  2. Ir a la página de destino

     // 退出登录
     router.get('/loginout',function(req,res,next){
       req.session.username = null;
       res.redirect('/login');
     })
    
Agregar, eliminar, modificar y verificar (escribir la función de publicación de artículos) ---- agregar
  1. Al escribir un artículo, debe utilizar el complemento de cuadro de texto enriquecido xhEditor:http://xheditor.com/download

  2. Después de descargar xhEditor, ponga la carpeta xheditor en nuestro proyecto, bajo pulice.
    Inserte la descripción de la imagen aquí

  3. Uso: introduzca archivos dependientes en el archivo html correspondiente e inicialice xheditor

     <script type="text/javascript" src="/xheditor/jquery/jquery-1.4.4.min.js"></script>
     <script type="text/javascript" src="/xheditor/xheditor-1.2.2.min.js"></script>
     <script type="text/javascript" src="/xheditor/xheditor_lang/zh-cn.js"></script>
     <script>
     // 其实在本项目中基本上用前两个就行了
     $('#elm1').xheditor({
         tools: 'full',
         skin: 'default',
         showBlocktag: true,
         internalScript: false,
         internalStyle: false,
         width: 300,
         height: 200,
         loadCSS: 'http://xheditor.com/test.css',
         fullscreen: true,
         sourceMode: true,
         forcePtag: true,
         upImgUrl: "upload.php",
         upImgExt: "jpg,jpeg,gif,png"
     });
    
  4. Agregue uno al elemento textarea class='xheditor', para que pueda ver el efecto cuando actualice la página
    Inserte la descripción de la imagen aquí

  5. Cree una nueva ruta article.js dedicada a la redacción de artículos. Luego configure el artículo en app.js:var articleRouter = require('./routes/article');app.use('/article', articleRouter);

  6. Al escribir un artículo para guardar, necesitamos agregar un dato para guardar el artículo en la base de datos de mongodb. Cuando lo enviamos, podemos guardarlo en la base de datos.

Implementación de la lista de artículos
  1. Nuevo artículo —— Después de escribir el artículo, se guarda en la base de datos en mongodb. Después de guardar, debe saltar a la página de inicio, por lo que la página de inicio debe tener una lista de artículos. Entonces, cuando estamos renderizando la ruta de la página de inicio. Opere mongodb y recupérelo de los datos de la lista correspondiente. Mostrar en la página

     router.get('/', function(req, res, next) {
       var username = req.session.username;
       model.connect(function(db){
         // 从库中,将articles文章张列表的数据。取出来转换成数组
         db.collection('articles').find().toArray(function(err,docs){
           console.log('文章列表------',docs);
           var list = docs; // 文章列表,用来传到index.ejs中
           res.render('index', { msg: '首页',username:username,list:list });
         });
       })
     });
    
  2. El tiempo que ahorramos en la biblioteca es de milisegundos. Sáquelo también, así que use un complemento para convertir la hora:npm install moment -S

  3. Uso moment: Introducir en el archivo requeridovar moment = require("moment");

     model.connect(function(db){
         // 从库中,将articles文章张列表的数据。取出来转换成数组
         db.collection('articles').find().toArray(function(err,docs){
           console.log('文章列表------',docs);
           var list = docs; // 文章列表,用来传到index.ejs中
           list.map(function(item){
             item.time = moment(item.id).format("YYYY-MM-DD hh:mm:ss");
             return item;
           })
           res.render('index', { msg: '首页',username:username,list:list });
         });
       })
    
Consulta de paginación
  1. js parte

     router.get('/', function(req, res, next) {
       var username = req.session.username || '';
       // 当前页
       var pageIndex = req.query.pageIndex || 1;
       // 分页
       var data = {
         total: 0,  // 文章总共的页数
         curPage: pageIndex,  // 当前页
         list: [],   // 当前页的文章列表
       }
       var pageSize = 10;  // 每次请求10条数据
       model.connect(function(db){
         // 第一步:查询所有文章(从库中,将articles文章张列表的数据。取出来转换成数组)
         db.collection('articles').find().toArray(function(err,docs){
           // 文章列表总条数/每页显示的条数,向上取整。得到一共有多少页。
           data.total = Math.ceil(docs.length / pageSize);
           // 第二步:查询当前页的文章列表(分页查询)
           model.connect(function(db){
             // 重点:sort({_id:-1})表示倒序查询;limit(pageSize)表示限制多少条;skip((pageIndex - 1)*pageSize)从多少条开始查
             db.collection('articles').find().sort({_id:-1}).limit(pageSize).skip((pageIndex - 1)*pageSize).toArray(function(err,doc2){
             // 这里考虑到如果删除的时候,当前页只剩一条数据,那么删完之后,需要把对应的页签也删掉。
               if(doc2.length == 0){
                 res.redirect('/?pageIndex='+((pageIndex-1) || 1));
                 return;
               }
               doc2.map(function(item){
                 item.time = moment(item.id).format("YYYY-MM-DD hh:mm:ss");
                 return item;
               })
               data.list = doc2;
             res.render('index', { msg: '首页',username:username,data:data });
             })
           })
         });
       })
     });
    
  2. ejs parte

     <!-- 分页 -->
       <div class="page">
         <span>共<%= data.list.length %>条</span>
         <a class="top">上一页</a>
         <% for(var i = 1; i<=data.total; i++){ %>
           <a href="/?pageIndex=<% i %>" class="pages"><%= i %></a>
         <% } %>
         <a class="next">下一页</a>
       </div>
    
Eliminar artículo
// ejs页面
<a href="/article/delete?id=<%= item.id %>&pageIndex=<%= data.curPage %>">删除</a>
// /delete路由代码
// 删除
router.get('/delete',function(req,res,next){
  var id = parseInt(req.query.id); // 页面传过来的需要删除的id
  var pageIndex = req.query.pageIndex; // 页面传过来的当前页
  model.connect(function(db){
  	// 删除对应id的数据deleteOne()
    db.collection('articles').deleteOne({id: id},function(err,ret){
      if(err){
        console.log('删除失败!!');
      }else{
        console.log('删除成功!!');
      }
      // 删除完成后接着跳转对应的页面路由,这里有一个问题,就是如果删除时只剩一条数据,那么删掉之后需要把那一页的分页也删掉。这个限制在主体路由上。
      res.redirect('/?pageIndex='+pageIndex);
    })
  })
})
modificar artículos
  1. Al hacer clic en Editar, la página y la nueva página comparten la misma página.

  2. Cuando se modifica: comparte la misma interfaz que la nueva y la misma colección de ruta de datos

     // 渲染写文章页面 || 编辑文章页面
     router.get('/write',function(req,res,next){
       var username = req.session.username;
       var id = parseInt(req.query.id);
       var pageIndex = req.query.pageIndex;
       var item = {
         title:'',  // 标题
         content:''  // 内容
       }
       if(id){  // 如果有id,那么就是编辑
         model.connect(function(db){
           db.collection('articles').findOne({id:id},function(err,docs){
             if(err){
               console.log('查询失败!!!!');
             }else{
               item = docs
               item.pageIndex = pageIndex;
               console.log('aaaaaaa-------',item);
               res.render('write',{msg:'编辑文章',username:username,item:item});
             }
           })
         })
       }else{  // 否则就是新增
         res.render('write',{msg:'写文章',username:username,item:item});
       }
     })
     /* 新增 || 编辑 */
     router.post('/add', function(req, res, next) {
       var id = parseInt(req.body.id);
       if(id){  // 编辑
         var pageIndex = req.body.pageIndex;
         var title = req.body.title;
         var content = req.body.content;
         model.connect(function(db){
           db.collection('articles').updateOne({id:id},{$set:{title:title,content:content}},function(err,ret){
               if(err){
                   console.log('文章修改失败!',err);
               }else{
                 console.log('文章修改成功!');
                   res.redirect('/?pageIndex='+pageIndex);
               }
           })
         })
       }else{   // 新增
         var data = {
           title: req.body.title,  // 标题
           content: req.body.content,  // 内容
           id: Date.now(),   // 时间戳(什么时候提交的)
           username: req.session.username  // 提交的用户(是谁写的)
         }
         model.connect(function(db){
           db.collection('articles').insert(data,function(err,ret){
               if(err){
                   console.log('文章发布失败!',err);
                   res.redirect('/write');
               }else{
                   res.redirect('/');
               }
           })
         })
       }
     });
    
Página de detalles del artículo (haga clic en el título para ver los detalles)
  1. La lógica básica es la misma que editar

  2. Crea una nueva página de detalles

     <td><a href="/detail?id=<%= item.id %>"><%= item.title %></a></td>
     ---------------------------------------------------
     // 查看文章详情页面
     router.get('/detail',function(req,res,next){
       var username = req.session.username;
       var id = parseInt(req.query.id);
       var item = {
         title:'',  // 标题
         username:'',  // 作者
         id:'',   // 时间&&id
         content:'',  // 内容
       }
       model.connect(function(db){
         db.collection('articles').findOne({id:id},function(err,docs){
           if(err){
             console.log('查询失败!!!!');
             res.redirect('/');
           }else{
             item = docs;
             item.time = moment(item.id).format('YYYY-MM-DD hh:mm:ss');
             res.render('detail',{msg:'详情页',username:username,item:item});
           }
         })
       })
     })
    
Carga de archivos (también a través del complemento de texto enriquecido xheditor)
  1. Parámetro de configuración
    Inserte la descripción de la imagen aquí

  2. Definido en el servidor/upload路由

  3. Se requiere un complemento de terceros para procesar las cargas de archivos multiparty, y el formato fijo de la carga debe sermultiparty/form-data

  4. Descargar:, npm install multiparty -SIntroducción:, var multiparty = require('multiparty');Crear instancias: después de la var form = new multiparty.Form()creación de instancias, el cuerpo de la solicitud se puede analizar a través del objeto de formulario, y los archivos en el cuerpo de la solicitud se pueden analizar y procesar. Obtenga el resultado que queremos;

     // 文件上传
     router.post('/upload',function(req,res,next){
       var form = new multiparty.Form();
       form.parse(req,function(err,fields,files){
         if(err){
           console.log('上传失败呗!!!');
         }else{
           console.log('文件列表----',files);
           // 这个就是拿到的上传的文件数据,我们需要使用fs管道流的方式,写入到硬盘
           var file = files.filedata[0];
           var newPath = '/uploads/'+file.originalFilename;  // 写入的路径加文件名字
           var rs = fs.createReadStream(file.path);  // 第一个流(读取的)--读的时候,就读带的路径就行
           var ws = fs.createWriteStream("./public"+newPath);  // 第二个流(写入的)--写的时候要写在服务端-这里放在pulice下的uploads中
           rs.pipe(ws);
           // 当写入完成的时候,监听一个on('close')事件
           ws.on('close',function(){
             console.log('文件上传成功!!!');
             res.send({err:'',msg:newPath});
           })
         }
       })
     })
    
resumen del proyecto

Una colección de registro, inicio de sesión, intercepción de inicio de sesión, almacenamiento de sesión, paginación y adición, eliminación, modificación y verificación de mongodb

Supongo que te gusta

Origin blog.csdn.net/weixin_43996999/article/details/103832849
Recomendado
Clasificación