Giter VIP home page Giter VIP logo

blog's Introduction

Blog

A blog system. Based on Vue2, Koa2, MongoDB and Redis

前后端分离 + 服务端渲染的博客系统, 前端 SPA + 后端 RESTful 服务器

Demo

前端:https://smallpath.me
后台管理截图:https://smallpath.me/post/blog-back-v2

Table of Contents

TODO

TODO

构建与部署

前置

  • Node v6
  • pm2
  • MongoDB
  • Redis

server

博客的提供RESTful API的后端

复制conf文件夹中的默认配置config.tpl, 并命名为config.js

有如下属性可以自行配置:

  • tokenSecret
    • 改为任意字符串
  • defaultAdminPassword
    • 默认密码, 必须修改, 否则服务器将拒绝启动

如果mongoDB或redis不在本机对应端口,可以修改对应的属性

  • mongoHost
  • mongoDatabase
  • mongoPort
  • redisHost
  • redisPort

如果需要启用后台管理单页的七牛图片上传功能,请再修改如下属性:

  • qiniuAccessKey
    • 七牛账号的公钥
  • qiniuSecretKey
    • 七牛账号的私钥
  • qiniuBucketHost
    • 七牛Bucket对应的外链域名
  • qiniuBucketName
    • 七牛Bucket的名称
  • qiniuPipeline
    • 七牛多媒体处理队列的名称
npm install
pm2 start entry.js

RESTful服务器在本机3000端口开启

front

博客的前台单页, 支持服务端渲染

复制server文件夹中的默认配置mongo.tpl, 并命名为mongo.js

如果mongoDB不在本机对应端口,请自行配置mongo.js中的属性:

  • mongoHost
  • mongoDatabase
  • mongoPort
npm install
npm run build
pm2 start production.js

请将logo.pngfavicon.ico放至static目录中

再用nginx代理本机8080端口即可, 可以使用如下的模板

server{
    listen 80;                                      #如果是https, 则替换80为443
    server_name *.smallpath.me smallpath.me;        #替换域名
    root /alidata/www/Blog/front/dist;       #替换路径为构建出来的dist路径
    set $node_port 3000;
    set $ssr_port 8080;

    location ^~ / {
        proxy_http_version 1.1;
        proxy_set_header Connection "upgrade";
        proxy_pass http://127.0.0.1:$ssr_port;
        proxy_redirect off;
    }

    location ^~ /proxyPrefix/ {
        rewrite ^/proxyPrefix/(.*) /$1 break;
        proxy_http_version 1.1;
        proxy_set_header Connection "upgrade";
        proxy_pass http://127.0.0.1:$node_port;
        proxy_redirect off;
    }

    location ^~ /dist/ {
        rewrite ^/dist/(.*) /$1 break;
        etag         on;
        expires      max;
    }

    location ^~ /static/ {
        etag         on;
        expires      max;
    }
}

开发端口为本机8080

admin

博客的后台管理单页
npm install
npm run build

用nginx代理构建出来的dist文件夹即可, 可以使用如下的模板

server{
    listen 80;                                     #如果是https, 则替换80为443
    server_name admin.smallpath.me;                #替换域名
    root /alidata/www/Blog/admin/dist;       #替换路径为构建出来的dist路径
    set $node_port 3000;

    index index.js index.html index.htm;

    location / {
        try_files $uri $uri/ @rewrites;
    }

    location @rewrites {
        rewrite ^(.*)$ / last;
    }

    location ^~ /proxyPrefix/ {
        rewrite ^/proxyPrefix/(.*) /$1 break;
        proxy_http_version 1.1;
        proxy_set_header Connection "upgrade";
        proxy_pass http://127.0.0.1:$node_port;
        proxy_redirect off;
    }

    location ^~ /static/ {
        etag         on;
        expires      max;
    }
}

开发端口为本机8082

后端 RESTful API

说明

后端服务器默认开启在 3000 端口, 如不愿意暴露 IP, 可以自行设置 nginx 代理, 或者直接使用前端两个单页的代理前缀/proxyPrefix

例如, demo的API根目录如下:

https://smallpath.me/proxyPrefix/api/:modelName/:id

其中, :modelName为模型名, 总计如下6个模型

post
theme
tag
category
option
user

:id为指定的文档ID, 用以对指定文档进行 CRUD

HTTP 动词

支持如下五种:

GET     //查询
POST    //新建
PUT     //替换
PATCH   //更新部分属性
DELETE  //删除指定ID的文档

有如下两个规定:

  • 对所有请求
    • header中必须将 Content-Type 设置为 application/json , 需要 body 的则 body 必须是合法 JSON格式
  • 对所有回应
    • header中的Content-Type均为application/json, 且返回的数据也是 JSON格式

权限验证

服务器直接允许对user模型外的所有模型的GET请求

user表的所有请求, 以及其他表的非 GET 请求, 都必须将 header 中的authorization设置为服务器下发的 Token, 服务器验证通过后才会继续执行 CRUD 操作

获得 Token

POST https://smallpath.me/proxyPrefix/admin/login

body格式如下:

{
	"name": "admin",
	"password": "testpassword"
}

成功, 则返回带有token字段的 JSON 数据

{
  "status": "success",
  "token": "tokenExample"
}

失败, 则返回如下格式的 JSON 数据:

{
  "status": "fail",
  "description": "Get token failed. Check name and password"
}

获取到token后, 在上述需要 token 验证的请求中, 请将 header 中的authorization设置为服务器下发的 Token, 否则请求将被服务器拒绝

撤销 Token

POST https://smallpath.me/proxyPrefix/admin/logout

header中的authorization设置为服务器下发的 token, 即可撤销此 token

Token说明

Token 默认有效期为获得后的一小时, 超出时间后请重新请求 Token
如需自定义有效期, 请修改服务端配置文件中的tokenExpiresIn字段, 其单位为秒

查询

服务器直接允许对user模型外的所有模型的 GET 请求, 不需要验证 Token

为了直接通过 URI 来进行 mongoDB 查询, 后台提供六种关键字的查询:

conditions,
select,
count,
sort,
skip,
limit

条件(conditions)查询

类型为JSON, 被解析为对象后, 直接将其作为mongoose.find的查询条件

查询所有文档

GET https://smallpath.me/proxyPrefix/api/post

查询title字段为'关于'的文档

GET https://smallpath.me/proxyPrefix/api/post?conditions={"title":"关于"}

查询指定id的文档的上一篇文档

GET https://smallpath.me/proxyPrefix/api/post/?conditions={"_id":{"$lt":"580b3ff504f59b4cc27845f0"}}&sort=1&limit=1

select查询

类型为JSON, 用以拾取每条数据所需要的属性名, 以过滤输出来加快响应速度

查询title字段为'关于'的文档的建立时间和更新时间

GET https://smallpath.me/proxyPrefix/api/post?conditions={"title":"关于"}&select={"createdAt":1,"updatedAt":1}

count查询

获得查询结果的数量

查询文档的数量

GET https://smallpath.me/proxyPrefix/api/post?conditions={"type":0}&count=1

sort查询

查询所有文档并按id倒序

GET https://smallpath.me/proxyPrefix/api/post?sort={"_id":-1}

查询所有文档并按更新时间倒序

GET https://smallpath.me/proxyPrefix/api/post?sort={"updatedAt":-1}

skip 查询和 limit 查询

查询第2页的文档(每页10条)并按时间倒叙

GET https://smallpath.me/proxyPrefix/api/post?limit=10&skip=10&sort=1

新建

需要验证Token

POST https://smallpath.me/proxyPrefix/api/:modelName

Body中为用来新建文档的JSON数据

每个模型的具体字段, 可以查看该模型的Schema定义来获得

替换

需要验证Token

PUT https://smallpath.me/proxyPrefix/api/:modelName/:id

:id为查询到的文档的_id属性, Body中为用来替换该文档的JSON数据

更新

需要验证Token

PATCH https://smallpath.me/proxyPrefix/api/:modelName/:id

:id为查询到的文档的_id属性, Body中为用来更新该文档的JSON数据

更新操作请使用PATCH而不是PUT

删除

需要验证 Token

DELETE https://smallpath.me/proxyPrefix/api/:modelName/:id

删除指定 ID 的文档

blog's People

Contributors

jerrybendy avatar qfdk avatar smallpath avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

blog's Issues

Patch请求和delete请求出问题

比如编辑更新一片文章,用patch请求访问 http://127.0.0.1:3000/api/post/58c95aa85d311c6e5000e3af 这个地址,出现了下面的错误,但是文章其实已经在数据库已经更新好了。
无论是更新(patch),删除(delete)文章,分类,标签等,都出现这种问题。
image

后台路由:
image

后台更新文章方法:
image

后台更新文章方法中console.log(result)的提示:
image

在前台使用的是fetch发起请求:
image

最奇怪的是get请求和post请求都没有问题,只有patch、delete、put请求出现这种问题。

单独跑server端插件依赖报错

node版本 6.10.2
npm版本 3.10.10

`> @ start E:\实验室\Vuejs\blog\server

node entry.js

E:\实验室\Vuejs\blog\server\node_modules\koa-ratelimit\index.js:40
return async function ratelimit(ctx, next) {
^^^^^^^^
SyntaxError: Unexpected token function
at createScript (vm.js:56:10)
at Object.runInThisContext (vm.js:97:10)
at Module._compile (module.js:542:28)
at Module._extensions..js (module.js:579:10)
at Object.require.extensions.(anonymous function) [as .js] (E:\实验室\Vuejs\blog\server\node_modules\babel-register\lib\node.js
52:7)`

关于七牛图片上传

您好,我现在有这样一个需要,因为要做一个很多图片展示类的网站,所以我再后台管理中创建一个基于element ui 上传组件的模板(模板中除了上传组件,还要保存图片的相关信息,即标题,创作的时间,左偏描述,也就是添加其他element ui组件,并绑定相应字段),我上传到七牛以后,并且填写了其他字段以后,我后台的接口是自己编写的,那么我后台的数据库是否应该保存这些字段(包括从七牛返回的url)。如果是这样的话,我想编辑该作品的时候应该怎么办?因为我后台只保存了图片的url,再次跟新的时候,是重写上传到七牛,然后再次更新数据库中的url吗?有没有什么办法,我更新图片的时候,七牛存储中的图片也更新?

文章页内容的展示

我想请教下博主,文章页面显示当前路由对应的文章内容的方法(在什么时候获取数据)

Front 部分的 mongo 配置未暴露出来以及一处文档错误

你好,

最近一直打算自己用 Node 写一套这样的博客系统,今天看到你的博客感觉不错,并且开源,于是试了下。以下提出一些建议以及 BUG。

建议:

  • 文件结构上面可以使 back 和 front 与 server 平级,表示是在同一个代码库中的三个子项目(或者直接拆成三个项目)
  • 建议把所有配置项单独放到一个文件中管理,例如类似 hexo 中的 .config.yml 文件
  • 配置文件添加支持使用环境变量传递,这样会大大方便在 docker 中部署及使用 pm2 传递环境变量的值
  • front 的代码中和服务相关的部分尽量完全脱离前端代码

BUG:

  • front 代码中有一处 mongo 的配置没有独立到配置文件中,位于 front/server/mongo.js 中,这会导致无法启动 front
  • 文档中 server 端的示例 nginx 配置中的 root 路径错了

有没有兴趣一起开发这套系统? 😀

Dockerfile 无法正常使用

使用 docker build -t blog . 进行docker 打包测试未能成功.

错误提示如下

npm ERR! Linux 4.9.13-moby
npm ERR! argv "/usr/local/bin/node" "/usr/local/bin/npm" "install" "-g" "yarn" "pm2"
npm ERR! node v7.7.4
npm ERR! npm  v4.1.2
npm ERR! path /usr/local/bin/yarn
npm ERR! code EEXIST

npm ERR! Refusing to delete /usr/local/bin/yarn: node_modules/npm/bin/npm-cli.js symlink target is not controlled by npm /usr/local
npm ERR! File exists: /usr/local/bin/yarn
npm ERR! Move it away, and try again.

npm ERR! Please include the following file with any support request:
npm ERR!     /npm-debug.log
The command '/bin/sh -c npm install -g yarn pm2' returned a non-zero code: 1

似乎现在改成了用 yarn 管理的方式

建议 docker 打成直接可运行的包(加上 mongo 和 redis)

还有个问题为什么要用 redis ?

几点建议

Hey

首先感谢作者的努力, 其次感谢大家对此项目的支持 :)

一下有几点意见,不知道意下如何。

  1. Dockerfile 能不能判断一下所在区域 ?上来就是cnpm让在vps跑的人很尴尬

  2. 搜索 我想加入Elasticsearch 因为看到了有Mongodb 可以同步数据进Elasticsearch

mongo-connector -m 127.0.0.1:27017 -t 127.0.0.1:9200 -d elastic_doc_manager
  1. 图床也可以照顾一下海外的盆友,qiniu 一直让填个手机号并且速度不是很快。我觉得imgur是个不错的选择 :)

  2. 前端这里可以考虑加个文件夹 比如默认用Default 然后用户可以自己设计一下主题。

翻了一下作者close的issues 回答都很详细,再次感谢。

有空了 会给这个项目出一份力 :)

带我一个玩呗?

我想弄个 VuePress,在谷歌上搜 spa 博客系统 ,就搜到你了,情投意合,一见钟情,看好你哦。
我能干点啥,也想出份力~

向大佬学习

关注大佬这个库也有一两年多了,现在我自己也写了个。wipi

Todo列表

readme里更新TODO不方便编辑和讨论,现在单独提到issue里,欢迎看到的大家提feature request

TODO

  • front

    • disqus评论
    • vue1.0升级至vue2.0
    • vuex单向数据流
    • 服务端渲染
    • 客户端谷歌统计
    • 服务端sitemap定时任务
    • 服务端rss定时任务
    • 组件级缓存
    • Loading组件
    • 侧边栏图片
    • 服务端谷歌统计
    • 全局404页面
    • 文章toc
    • 页面meta
    • 按需分块加载
    • service worker缓存所有资源
    • SSR服务端直连mongo
    • 自制axios以减小打包大小
    • 自制vuex以减小打包大小
    • SSR服务端不可用时进行降级
    • import替换require.ensure
    • 修复中文链接刷新时404的问题
    • blogPager增加查看更多链接
    • footer显示备案号
    • 修改倒序查询条件
    • vue2.3.0 ssr变更
  • admin

    • vue1.0升级至vue2.0
    • 使用element ui
    • 七牛云图片上传
    • 文章toc的生成与编辑
    • 草稿的自动生成与手动恢复
    • 上传图片后指定img标签的高度以避免闪烁
    • 扫描所有文章,指定img高度
    • 修改倒序查询条件
    • 文章增加标题图片的编辑功能
  • server

    • RESTful添加select字段过滤
    • 标签及分类移至文章中
    • 七牛access_token下发及鉴权
    • lint
    • RESTful的排序自定义
    • 防CC
    • 按天备份
    • redis做一层缓存层
  • 其他

    • CI
    • i18n
    • 搜索
      • es
      • algolia
    • API增加v1头
  • RPC不做了,就算做了效果也没直连数据库好

  • 后端会重构一次,计划支持类似webpack config的插件形式

    • 提供类webpack打包生命周期的中间件,否则增加新功能对代码侵入性太高了,也可以降低社区贡献代码的难度
  • 七牛等敏感配置放到admin上,图形界面比较好

  • 增加一个安装页面,用来在图形界面输入初始参数

  • 增加文档站,使用docsify,可能会放到另外的仓库里

  • 最后是组织,需要给博客取个名字(好难🤣),转移仓库过去

前端安装失败

ERROR in ./src/client-entry.js
Module build failed: Error: Couldn't find preset "latest" relative to directory "/Users/seseemu/Blog/client/front"

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.