ホームページ  >  記事  >  ウェブフロントエンド  >  node.js ブログ プロジェクト開発経験の共有

node.js ブログ プロジェクト開発経験の共有

小云云
小云云オリジナル
2018-03-19 09:43:171999ブラウズ

この記事は主に、node.js ブログプロジェクトの開発とナレッジポイントの共有に関連する手順をまとめたもので、興味のある友人が参考になれば幸いです。

インストールする必要があるモジュール

  • body-parser 投稿リクエストを解析

  • cookie Cookieの読み取りと書き込み

  • express サーバーの構築

  • markdown構文解析ジェネレーター

  • mongoose Mongodb データベースの操作

  • swig テンプレート解析エンジン

ディレクトリ構造

  • db データベース格納ディレクトリ

  • models データベース モデル ファイル ディレクトリ

  • public パブリック ファイル ディレクトリ (css) 、 js 、 img)

  • ルーター ルーティング ファイル ディレクトリ

  • スキーマ データベース構造ファイル

  • ビュー テンプレート ビュー ファイル ディレクトリ

  • app.js 起動ファイル

  • package.json

app.js ファイル

1. アプリケーションとリッスン ポートを作成します

使用するテンプレート エンジンを定義します

    パラメーター 1:テンプレートエンジン 名前はテンプレートファイルの接尾辞パラメータでもあります 2: テンプレートコンテンツの解析と処理に使用されるメソッドを示します
  • テンプレートファイルが保存されているディレクトリを設定します app.set('views','./ views')
  • 登録 テンプレートエンジンはapp.set('view Engine','html')を使用します
  • 3. テンプレートエンジンを使用してファイルを解析します

4.開発プロセス中にテンプレートのキャッシュ制限を解除するために必要です

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");
});

5. 静的ファイルホスティングを設定します

/**
 * 读取views目录下的指定文件,解析并返回给客户端 
 * 参数1:模板文件
 * 参数2:给模板传递的参数 
 */
 
res.render('index',{
  title:'首页 ',
  content: 'hello swig'
});

フロントエンドモジュール


バックエンドモジュール

  • APIモジュール

  • swig.setDefaults({
     cache: false
    });
    app.set('view cache', false);
  • 管理用メンバーモジュール admin.js

 // 当用户访问的是/public路径下的文件,那么直接返回
app.use('/public',express.static(__dirname + '/public'));

フロントエンドルーティング+テンプレート

メインモジュール

/ホームページ

/viewページ


apiモジュール



/Homepage
/register ユーザー登録

/login ユーザーログイン

/comment コメント取得/comment/post コメント投稿

バックエンド(管理者)ルーティング+テンプレート



Homepage

/Backendホームページ

ユーザー管理


/user ユーザーリスト


カテゴリ管理


/category カテゴリリスト

/category/add カテゴリ追加

/category/edit カテゴリ変更
/category/delete カテゴリ削除


記事コンテンツ管理


/article nei コンテンツリスト
/article/add content 追加
/article/edit コンテンツ修正
/article/delete コンテンツ削除


コメントコンテンツ管理


/comment コメントリスト
/comment/delete コメント削除

関数開発シーケンス


機能モジュール開発シーケンス


User


Column

  • Content

  • Comments

  • エンコード順序

  • スキーマ定義によるデータストレージ構造の設計

関数ロジック

  • ページ表示

  • データベース(mongoDB)に接続

  • MongoDBサーバーを起動します:

  • mongod --dbpath=G:datadb --port=27017


サービスを開始し、データベースのストレージ アドレスとポートを設定します


// 根据不同的功能划分模块
app.use('/',require('./routers/main'));
app.use('/admin',require('./routers/admin'));
app.use('/api',require('./routers/api'));


定義 データ テーブルの構造とモデル

スキーマ フォルダー内のユーザー データ テーブル (users.js) の場合:

var express = require('express');
var router = express.Router();

// 比如访问 /admin/user
router.get('/user',function(req,res,next) {
  res.send('User');
});
module.exports = router;

models ディレクトリに user.js モデル クラスを作成します

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");
    });
  }
});

ユーザー登録の処理

フロントエンドは ajax を通じてユーザー名とパスワードを送信します

url: /api/register フロントエンド送信(POST)のバックエンドデータ分析

var mongoose = require('mongoose');
module.exports = new mongoose.Schema({
  // 用户名
  username:String,
  // 密码
  password:String
});

Cookieモジュールの使用

グローバル(app.js)

var mongoose = require('mongoose');
var userSchema = require('../schemas/users');
module.exports = mongoose.model('User',userSchema);


swigテンプレートエンジンを使用して登録

1. 変数

{{ name }}


2. 属性


{{ Student.name }}

3.if 判定


{ % if name === 'Guo Jing ' % }

こんにちは、Jing 兄弟

{ % endif % }

4.for ループ

// arr = [ 1, 2, 3]

{ % for key, val in arr % }

e388a4556c0f65e1904146cc1a846bee{ { key } } -- { { val } }94b3e26ee717c64999d7867364b1b4a3

{ % endfor % }

5.set コマンド

は、変数を設定して再利用するために使用されます。現在のコンテキスト


{% set foo = [0, 1, 2, 3, 4, 5] %}

{% extends 'layout.html' %} // 特定の HTML テンプレートを継承します
{% include ' page.html' %} // 現在の場所にテンプレートをインクルードします

{% block main %} xxx {% endblock %} // 特定の One ブロックを書き換えます

6.autoescape 自動エンコード

当想在某个p中显示后端生成的HTML代码,模板渲染时会自动编码,
以字符串的形式显示。通过以下方式,可以避免这个情况:

<p id="article-content" class="content">
  {% autoescape false %}
  {{ data.article_content_html }}
  {% endautoescape %}
</p>

用户管理和分页

CRUD用户数据

const User = require(&#39;../models/user&#39;);

// 查询所有的用户数据
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(&#39;mongoose&#39;);
var contentSch = require(&#39;../schemas/contentSch&#39;);

module.exports = mongoose.model(&#39;Content&#39;,contentSch);


// contentSch.js
module.exports = new mongoose.Schema({
  
  // 关联字段 - 分类的id
  category:{
    // 类型
    type:mongoose.Schema.Types.ObjectId,
    // 引用
    ref:&#39;Category&#39; 
  },
  
  // 内容标题
  title: String,
  
  // 简介
  description:{
    type: String,
    default: &#39;&#39; 
  },
  
  // 内容
  content:{
    type:String,
    default:&#39;&#39;
  }
});

// 文章查询时关联category字段
Content.find().populate(&#39;category&#39;).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语法解析内容预览
$(&#39;#bjw-content&#39;).on(&#39;keyup blur&#39;, function () {
  $(&#39;#bjw-previous&#39;).html(marked($(&#39;#bjw-content&#39;).val()));
});

node环境中使用

// 在模板页面引入默认样式
<!--语法高亮-->
<link rel="stylesheet" href="http://cdnjs.cloudflare.com/ajax/libs/highlight.js/9.12.0/styles/default.min.css">

const marked = require(&#39;marked&#39;);
const hljs = require(&#39;highlight.js&#39;);

// 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缩进

$(&#39;#bjw-content&#39;).on(&#39;keydown&#39;,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: &#39;t&#39;,
    icon: icon,
    content: text,
    btn: false,
    title: false,
    closeBtn: 0,
    end: function () {
      callback && callback();
    }
  });
});

随机用户头像生成

// 引入对应的库
const crypto = require(&#39;crypto&#39;);
const identicon = require(&#39;identicon.js&#39;);

// 当用户注册时,根据用户的用户名生成随机头像
let hash = crypto.createHash(&#39;md5&#39;);
hash.update(username);
let imgData = new identicon(hash.digest(&#39;hex&#39;).toString());
let imgUrl = &#39;data:/image/png;base64,&#39;+imgData;

orm表单提交的小问题

当使用form表单提交一些代码的时候,会出现浏览器拦截的现象,原因是:浏览器误以为客户进行xss攻击。所以呢解决这个问题也很简单,就是对提交的内容进行base64或者其他形式的编码,在服务器端进行解码,即可解决。

以上がnode.js ブログ プロジェクト開発経験の共有の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。