Heim > Artikel > Web-Frontend > Hinweise zur Entwicklung des Blog-Projekts von node.js
Dieser Artikel fasst die relevanten Schritte und Wissenspunkte für die Entwicklung des Node.js-Blogprojekts zusammen. Interessierte Freunde können darauf verweisen.
Module, die installiert werden müssen
Body-Parser analysiert Post-Anfragen
Cookies Cookies lesen und schreiben
Express-Build-Server
Markdown Markdown-Syntax-Parsing-Generator
Mungo-Betrieb Mongodb-Datenbank
Swig-Template-Parsing-Engine
Verzeichnisstruktur
DB-Datenbankspeicherverzeichnis
Modelldatenbank-Modelldateiverzeichnis
öffentliches öffentliches Dateiverzeichnis (CSS, JS, img)
Router-Routing-Dateiverzeichnis
Schema-Datenbankstrukturdatei
Ansichtsvorlage, Ansichtsdatei Verzeichnis
app.js-Startdatei
package.json
app.js-Datei
1. Anwendung und Abhörport erstellen
const app = express(); app.get('/',(req,res,next) => { res.send("Hello World !"); }); app.listen(3000,(req,res,next) => { console.log("app is running at port 3000"); });
2. Anwendungsvorlage konfigurieren
Definition Die verwendete Vorlagen-Engine app.engine('html',swig.renderFile) Parameter 1: Der Name der Vorlagen-Engine, der auch das Suffix der Vorlagendatei ist. Parameter 2: Gibt die Methode an, die zum Parsen und Verarbeiten der Vorlage verwendet wird Inhalt
Legen Sie das Verzeichnis fest, in dem Vorlagendateien gespeichert werden app.set('views','./views')
Registrieren Sie die Vorlage verwendete Engine app.set('view engine' ,'html')
3. Verwenden Sie die Template-Engine, um die Datei zu analysieren
/** * 读取views目录下的指定文件,解析并返回给客户端 * 参数1:模板文件 * 参数2:给模板传递的参数 */ res.render('index',{ title:'首页 ', content: 'hello swig' });
Während des Entwicklungsprozesses erforderlich. Einschränkungen beim Vorlagen-Caching aufheben
swig.setDefaults({ cache: false }); app.set('view cache', false);
5. Richten Sie statisches Datei-Hosting ein
// 当用户访问的是/public路径下的文件,那么直接返回 app.use('/public',express.static(__dirname + '/public'));
Partitionsmodul
Front-End-Modul
Back-End-Modul
API-Modul
// 根据不同的功能划分模块 app.use('/',require('./routers/main')); app.use('/admin',require('./routers/admin')); app.use('/api',require('./routers/api'));
Für Admin-Modul admin.js
var express = require('express'); var router = express.Router(); // 比如访问 /admin/user router.get('/user',function(req,res,next) { res.send('User'); }); module.exports = router;
Frontend-Routing + Vorlage
Hauptmodul
/ Startseite
/Inhaltsseite anzeigen
API-Modul
/Homepage
/register Benutzerregistrierung
/login Benutzeranmeldung
/comment Kommentarerfassung
/comment/post Kommentarübermittlung
Backend (admin )Route+Template
Homepage
/ Backend-Homepage
Benutzerverwaltung
/Benutzer Benutzerliste
Kategorieverwaltung
/Kategorie Kategorieliste
/Kategorie/Kategorie hinzufügen Hinzufügen
/Kategorie/Kategorie bearbeiten
/Kategorie/Kategorie löschen Löschen
Artikelinhaltsverwaltung
/Artikel und Inhaltsliste
/Artikel /Inhalt hinzufügen hinzufügen
/Artikel/Inhaltsänderung bearbeiten
/Artikel /löschen Inhalt löschen
Kommentarinhaltsverwaltung
/Kommentar-Kommentarliste
/comment/delete comment delete
Funktionsentwicklungssequenz
Funktionsmodulentwicklungssequenz
Benutzer
Spalte
Inhalt
Kommentare
Kodierungsreihenfolge
Entwerfen Sie eine durch Schema definierte Datenspeicherstruktur
Funktionslogik
Seitenanzeige
Mit Datenbank (mongoDB) verbinden
MongoDB-Server starten:
mongod --dbpath=G:datadb --port=27017
Starten Sie den Dienst und legen Sie die Speicheradresse und den Port der Datenbank fest
var mongoose = require('mongoose'); // 数据库链接 mongoose.connect("mongodb://localhost:27017/blog",(err) => { if(err){ console.log("数据库连接失败"); }else{ console.log("数据库连接成功"); // 启动服务器,监听端口 app.listen(3000,(req,res,next) => { console.log("app is running at port 3000"); }); } });
Definieren Sie die Struktur und das Modell der Datentabelle
Für die Benutzerdatentabelle (users.js) im Schemaordner:
var mongoose = require('mongoose'); module.exports = new mongoose.Schema({ // 用户名 username:String, // 密码 password:String });
Erstellen Sie die Modellklasse user.js im Modellverzeichnis
var mongoose = require('mongoose'); var userSchema = require('../schemas/users'); module.exports = mongoose.model('User',userSchema);
Benutzerregistrierung verarbeiten
Front-End übermittelt Benutzernamen und Passwort über Ajax
URL: /api/register
Back-End übermittelt Datenanalyse an Front-End (POST)
var bodyParser = require('body-parser'); // bodyParser 配置 // 通过使用这一方法,可以为req对象添加一个body属性 app.use( bodyParser.urlencoded({extended:true})); // 在api模块中: // 1.可以定义一个中间件,来统一返回格式 var responseData; router.use( function(req,res,next){ // path默认为'/',当访问该目录时这个中间件被调用 responseData = { code:0, message:'' }; next(); }); router.post('/register',(req,res,next) => { console.log(req.body); // 去判断用户名、密码是否合法 // 判断是否用户名已经被注册 // 通过 res.json(responseData) 给客户端返回json数据 // 查询数据库 User.findOne({ // 返回一个promise对象 username: username }).then(function( userInfo ) { if( userInfo ){ // 数据库中有该条记录 ... res.json(responseData); return; } // 给数据库中添加该条信息 var user = new User({ username:username,password:password }); return user.save(); // 返回promise对象 }).then(function( newUserInfo ){ console.log(newUserInfo); res.json(responseData); // 数据保存成功 }); });
Nutzung des Cookie-Moduls
Globale (app.js) Registrierung
// 设置cookie // 只要客户端发送请求就会通过这个中间件 app.use((req, res, next) => { req.cookies = new cookies(req, res); /** * 解析用户的cookies信息 * 查询数据库判断是否为管理员 isAdmin * 注意:查询数据库是异步操作,next应该放在回调里边 */ req.userInfo = {}; if (req.cookies.get("userInfo")) { try { req.userInfo = JSON.parse(req.cookies.get("userInfo")); // 查询数据库判断是否为管理员 User.findById(req.userInfo._id).then(function (result) { req.userInfo.isAdmin = Boolean(result.isAdmin); next(); }); } catch (e) { next(); } } else { next(); } }); // 当用户登录或注册成功之后,可以为其设置cookies req.cookies.set("userInfo",JSON.stringify({ _id:result._id, username:result.username }));
swig template engine
Variablen
{{ name }}
2. Attribute
{{ student.name }}
3.if Urteil
{ % if name === 'Guo Jing' % }
Hallo Bruder Jing
{ % endif % }
4.for-Schleife
// arr = [1, 2, 3]
{ % für Schlüssel, Wert in arr % }
e388a4556c0f65e1904146cc1a846bee{ { key } } -- { { val } }94b3e26ee717c64999d7867364b1b4a3
{ % endfor % }
5.set command
wird verwendet, um eine Variable festzulegen und im aktuellen Kontext wiederzuverwenden
{% set foo = [0, 1, 2, 3, 4, 5] %}
{% extensions ' layout.html' %} // Eine bestimmte HTML-Vorlage erben
{% include 'page.html' %} // Eine Vorlage in die aktuelle Position einfügen
{% block main %} xxx {% endblock %} / / Einen bestimmten Block neu schreiben
6.Autoescape automatische Codierung
Wenn Sie möchten, wird der vom Backend generierte HTML-Code in einem bestimmten Bereich angezeigt. Er wird automatisch codiert, wenn der Die Vorlage wird gerendert und
wird in Form einer Zeichenfolge angezeigt. Diese Situation kann vermieden werden durch:
<p id="article-content" class="content"> {% autoescape false %} {{ data.article_content_html }} {% endautoescape %} </p>
Benutzerverwaltung und Paging
CRUD用户数据
const User = require('../models/user'); // 查询所有的用户数据 User.find().then(function(users){ }); // 根据某一字段查询数据 User.findOne({ username:username }).then(function(result){ }); // 根据用户ID查询数据 User.findById(id).then(function(user){ }); // 根据ID删除数据 User.remove({ _id: id }).then(function(){ }); // 修改数据 User.update({ _id: id },{ username: name }).then(function(){ });
数据分页管理
两个重要方法
limit(Number): 限制获取的数据条数
skip(Number): 忽略数据的条数 前number条
忽略条数:(当前页 - 1) * 每页显示的条数
// 接收传过来的page let query_page = Number(req.query.page) || 1; query_page = Math.max(query_page, 1); // 限制最小为1 query_page = Math.min(Math.ceil(count / limit), query_page); // 限制最大值 count/limit向上取整 var cur_page = query_page; // 当前页 var limit = 10; // 每页显示的条数 var skip = (cur_page - 1) * limit; //忽略的条数 User.find().limit(limit).skip(skip).then(function(users){ ... // 将当前页 page 传给页面 // 将最大页码 maxPage 传给页面 });
文章的表结构
// 对于content.js var mongoose = require('mongoose'); var contentSch = require('../schemas/contentSch'); module.exports = mongoose.model('Content',contentSch); // contentSch.js module.exports = new mongoose.Schema({ // 关联字段 - 分类的id category:{ // 类型 type:mongoose.Schema.Types.ObjectId, // 引用 ref:'Category' }, // 内容标题 title: String, // 简介 description:{ type: String, default: '' }, // 内容 content:{ type:String, default:'' } }); // 文章查询时关联category字段 Content.find().populate('category').then(contents => { // 那么通过这样的方式,我们就可以找到Content表中的 // 关联信息 content.category.category_name });
MarkDown语法高亮
在HTML中直接使用
<link rel="stylesheet" href="http://cdnjs.cloudflare.com/ajax/libs/highlight.js/9.12.0/styles/default.min.css"> <script src="http://cdnjs.cloudflare.com/ajax/libs/highlight.js/9.12.0/highlight.min.js"></script> <script src="https://cdn.bootcss.com/marked/0.3.17/marked.min.js"></script> // marked相关配置 marked.setOptions({ renderer: new marked.Renderer(), gfm: true, tables: true, breaks: false, pedantic: false, sanitize: true, smartLists: true, smartypants: false, highlight: function (code) { return hljs.highlightAuto(code).value; } }); // MarkDown语法解析内容预览 $('#bjw-content').on('keyup blur', function () { $('#bjw-previous').html(marked($('#bjw-content').val())); });
node环境中使用
// 在模板页面引入默认样式 <!--语法高亮--> <link rel="stylesheet" href="http://cdnjs.cloudflare.com/ajax/libs/highlight.js/9.12.0/styles/default.min.css"> const marked = require('marked'); const hljs = require('highlight.js'); // marked相关配置 marked.setOptions({ renderer: new marked.Renderer(), gfm: true, tables: true, breaks: false, pedantic: false, sanitize: true, smartLists: true, smartypants: false, highlight: function (code) { return hljs.highlightAuto(code).value; } }); // 对内容进行markdown语法转换 data.article_content_html = marked(article.content);
使文本域支持Tab缩进
$('#bjw-content').on('keydown',function(e){ if(e.keyCode === 9){ // Tab键 var position = this.selectionStart + 2; // Tab === 俩空格 this.value = this.value.substr(0,this.selectionStart) + " " + this.value.substr(this.selectionStart); this.selectionStart = position; this.selectionEnd = position; this.focus(); e.preventDefault(); } });
layer 弹框
// 显示弹框 function showDialog(text, icon, callback) { layer.open({ time: 1500, anim: 4, offset: 't', icon: icon, content: text, btn: false, title: false, closeBtn: 0, end: function () { callback && callback(); } }); });
随机用户头像生成
// 引入对应的库 const crypto = require('crypto'); const identicon = require('identicon.js'); // 当用户注册时,根据用户的用户名生成随机头像 let hash = crypto.createHash('md5'); hash.update(username); let imgData = new identicon(hash.digest('hex').toString()); let imgUrl = 'data:/image/png;base64,'+imgData;
orm表单提交的小问题
当使用form表单提交一些代码的时候,会出现浏览器拦截的现象,原因是:浏览器误以为客户进行xss攻击。所以呢解决这个问题也很简单,就是对提交的内容进行base64或者其他形式的编码,在服务器端进行解码,即可解决。
上面是我整理给大家的,希望今后会对大家有帮助。
相关文章:
Das obige ist der detaillierte Inhalt vonHinweise zur Entwicklung des Blog-Projekts von node.js. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!