>  기사  >  웹 프론트엔드  >  node.js 블로그 프로젝트 개발 노트

node.js 블로그 프로젝트 개발 노트

亚连
亚连원래의
2018-05-29 18:02:032167검색

이 글은 node.js 블로그 프로젝트 개발과 관련된 단계와 지식 포인트를 요약한 것입니다. 관심 있는 친구들이 참고할 수 있습니다.

설치해야 하는 모듈

  • body-parser 게시물 요청 구문 분석

  • cookies 쿠키 읽기 및 쓰기

  • express 서버 구축

  • markdown 마크다운 구문 분석 생성기

  • mongoose 작업 Mongodb 데이터베이스

  • swig 템플릿 구문 분석 엔진

디렉터리 구조

  • db 데이터베이스 저장 디렉터리

  • models 데이터베이스 모델 파일 디렉터리

  • public 공용 파일 디렉터리(css , js, img)

  • 라우터 라우팅 파일 디렉터리

  • 스키마 데이터베이스 구조 파일

  • 뷰 템플릿 보기 파일 디렉터리

  • app.js 시작 파일

  • package.json

app.js 파일

1. 애플리케이션 및 수신 포트 생성

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. 애플리케이션 템플릿 구성

  • app.engine('html',swig.renderFile) 매개변수 1을 정의합니다. 템플릿 엔진 이름은 템플릿 파일의 접미사 매개변수이기도 합니다. 2: 템플릿 콘텐츠를 구문 분석하고 처리하는 데 사용되는 방법을 나타냅니다

  • 템플릿 파일이 저장된 디렉터리를 설정합니다. app.set('views','./ views')

  • 등록 사무실 app.set('viewengine','html')

3 템플릿 엔진을 사용하여 파일을 구문 분석합니다

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

4. 개발 프로세스 중에 템플릿 캐시 제한을 취소해야합니다

API 모듈

swig.setDefaults({
 cache: false
});
app.set('view cache', false);

For Admins Module admin.js

     // 当用户访问的是/public路径下的文件,那么直接返回
    app.use('/public',express.static(__dirname + '/public'));
  • 프런트엔드 라우팅 + 템플릿
  • 메인 모듈
  • /Homepage

    /view 콘텐츠 페이지

api 모듈

/Homepage

/register user 등록

/login 사용자 로그인

/comment 댓글 획득

/comment/post 댓글 제출

백엔드(관리자) 라우팅 + 템플릿

Homepage



/백엔드 홈페이지

사용자 관리
/user 사용자 목록


카테고리 관리


/category 카테고리 목록

/category/add 카테고리 추가

/category/edit 카테고리 수정/category/delete 카테고리 삭제

글 콘텐츠 관리

/article nei 콘텐츠 목록
/article/add 콘텐츠 추가

/article/edit 콘텐츠 수정

/article/delete 콘텐츠 삭제

댓글 콘텐츠 관리

/comment 댓글 목록
/comment/ delete 댓글 삭제

함수 개발 순서


함수 모듈 개발 순서


User



column

content


comments


encoding order

  • 설계 데이터 저장소 정의 스키마를 통한 구조

  • 기능적 논리

  • 페이지 표시

  • 연결 데이터베이스(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;


모델 디렉토리에 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를 통해 사용자 이름과 비밀번호를 제출합니다. PROST-END 제출 (POST)의 백 엔드 데이터 분석 쿠키 모듈의 쿠키 모듈 (APP.JS) 레지스터를 사용하여

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

swig 템플릿 엔진

변수

{{ 이름 }}

2. 속성

{{ 학생.이름 }}

3. if 판단

{ % if 이름 === 'Guo Jing' % }

안녕하세요 Jing 형제님

{ % endif % }


4.for loop

// arr = [1, 2, 3]

{ % for key, val in arr % }

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

{ % endfor % }

5.set 명령
  1. 이 사용됩니다. 변수를 설정하고 현재 컨텍스트에서 재사용합니다

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

    {% 확장 'layout.html' %} // 특정 HTML 템플릿 상속
  2. {% include 'page.html' %} //템플릿 포함 현재 위치
{% block main %} xxx {% endblock %} //특정 블록 다시 쓰기

6.autoescape 자동 인코딩

백엔드에서 생성한 HTML 코드를 특정 p에 표시하고 싶을 때, 템플릿이 렌더링될 때 자동으로 인코딩되어

문자열 형식으로 표시됩니다. 다음을 통해 이를 피할 수 있습니다:

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

사용자 관리 및 페이지 매김

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语法解析内容预览
$(&#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或者其他形式的编码,在服务器端进行解码,即可解决。

上面是我整理给大家的,希望今后会对大家有帮助。

相关文章:

javascript实现文件拖拽事件

vue文件树组件使用详解

vue全局组件与局部组件使用方法详解

위 내용은 node.js 블로그 프로젝트 개발 노트의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.