使用node.js + express开发后台

开发环境node.js + express

express.gif

复制项目

# 将项目克隆到本地
    git clone https://github.com/peng1992/express.git
# 安装项目依赖
    cnpm install
# 启动项目
    cnpm start

然后在浏览器中打开http://localhost:3000/ 网址就可以看到这个应用了

normal.png

项目目录

  • bin/
    • www -------------------------项目入口文件
  • node_modules/ -------------------项目依赖文件夹,cnpm intall后生成
  • public/
    • data/ ------------------------json数据
    • images/ ---------------------图片
    • js/ -------------------------js文件
    • stylesheets/ -----------------css文件
  • routes/ -------------------------路由配置文件夹
    • data.js
    • index.js
  • views/ -------------------------模板文件
    • edit.ejs
    • error.ejs
    • index.ejs
    • login.ejs
    • tujian.ejs
  • app.js --------------------------存放的Express项目中最基本的配置信息
  • package.json --------------------项目依赖文件

文件解析

app.js

// 引入资源文件
var express = require('express');
var path = require('path');
var favicon = require('serve-favicon');
var logger = require('morgan');
var cookieParser = require('cookie-parser');
var bodyParser = require('body-parser');

var index = require('./routes/index');  ---------------------------引入index.js路由配置文件
var data = require('./routes/data');    ---------------------------引入data.js路由配置文件

var app = express();    -------------------------------------------用express创建一个app应用

// 视图引擎设置
app.set('views', path.join(__dirname, 'views'));    ---------------指定视图文件夹 views/
app.set('view engine', 'ejs');  -----------------------------------指定视图引擎 ejs

// 使用刚刚加载的资源
//app.use(favicon(path.join(__dirname, 'public', 'favicon.ico')));
app.use(logger('dev'));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));
app.use(cookieParser());    --------------------------------------- 使用cookie
app.use(express.static(path.join(__dirname, 'public')));    -----------指定公共资源文件夹 为public/

app.use('/', index);    ----------------------------当路径为'/',即'http://localhost:3000/'时,匹配index.js
app.use('/data', data);     ------------------------当路径为'/data',即'http://localhost:3000/data'时,匹配data.js
// 匹配404,即路径未匹配时
app.use(function(req, res, next) {
  var err = new Error('Not Found');
  err.status = 404;
  next(err);
});

// 当路径匹配错误时
app.use(function(err, req, res, next) {
  // set locals, only providing error in development
  res.locals.message = err.message;
  res.locals.error = req.app.get('env') === 'development' ? err : {};

  // render the error page
  res.status(err.status || 500);
  res.render('error');
});

module.exports = app;

index.js页面定义的接口如下:(全部为get请求)

  • / -----------------------首页
  • /edit?type=it -----------------------------互联网
  • /edit?type=cookies ---------------------笑料
  • /edit?type=manager --------------------管理
  • /edit?type=sanwen ----------------------散文
  • /tuijian -------------------------------------推荐

index.js是怎样定义这些接口呢?

router.get('/edit', function(req, res, next) {...}

以'/edit'为url的ajax请求,就会执行上面的回调函数,让我们来看一下回调函数里面都写了些什么?

router.get('/edit', function(req, res, next) {
      if(!req.cookies.user){    ---------------------------判断用户是否已登录
          return res.render('login',{});
      }
      var type = req.query.type;    ----------------------获取查询参数type的值
      if(type){ ---------------------------如果查询参数存在
        var obj = {};
        switch(type){   ---------------------------------根据不同的type,返回不同的值
          case 'sanwen':
            obj = {};
            break;
          case 'it':
            obj = {};
            break;
          case 'manager':
            obj = {};
            break;
          case 'cookies':
            obj = {};
            break;
          default :
                return res.send({
                  status:0,
                  info:'参数错误'
                });
          break;
        }
        fs.readFile(PATH + type + '.json', (err, data) => { ------------------------------ 读取文件,并执行回调函数              if (err) {
          if (err) {    ---------------------------------如果读取失败
            return res.send({
              status:0, ---------------------------------返回错误状态码0
              info: 'fail.....'
            });
          }

          var obj = JSON.parse(data.toString());
          return res.render('edit', {   ----------否则,如果读取成功,渲染模板edit.jsp,返回数据obj
            data: obj
          });
        });
      }else {   -------------------------------------------如果查询参数不存在
        return res.send({
          status:0,
          info: '参数错误'
        });
      }
    });

打开http://localhost:3000/edit?type=it,会提示需要登录,

login.png

用户登录接口/login,在data.js中设置,账号admin密码12345,登录成功后,会出现如下界面

it.png

data.js定义的接口

  • 读数据接口---get请求

    • /write?type=it ------------------------------------读取it.json中的数据
    • /write?type=cookies
    • /write?type=manager
    • /write?type=sanwen
    • /write?type=tuijian
  • 写入数据接口----post请求

    • /write?type=it ------------------------------------向it.json写入数据
    • /write?type=cookies
    • /write?type=manager
    • /write?type=sanwen
    • /write?type=tuijian
  • 阅读模块写入数据接口----post请求

    • /write_config
  • 登录接口----post请求

    • /login

以写入数据接口为例,'/write?type=it'会执行下面的代码

    router.post('/write',function(req, res, next){
        if(!req.cookies.user){  ------------------------判断是否已登录
            return res.render('login',{});
        }
        // 文件名
        var type = req.param('type') || ""; -------------------------获取请求参数type的值
        // 关键字段
        var url = req.param('url') || '';   -------------------------获取请求参数url的值
        var title = req.param('title') || '';   ---------------------获取请求参数title的值            var img = req.param('img') || '';
        if(!type || !url || !title || !img){    ---------------------如果这些请求参数有一个不存在
            return res.send({
                status:0,
                info:'提交的字段不全'
            });
        }
        //1)读取文件
        var filePath = PATH + type + '.json';   --------------------否则,会读取对应的json文件
        fs.readFile(filePath, function(err, data){
            if(err){    --------------------------如果读取数据失败
                return res.send({   --------------返回错误状态信息
                    status:0,
                    info: '读取数据失败'
                });
            }
                        ------------------------如果读取数据成功,则继续执行
            var arr = JSON.parse(data.toString());  ----------------------将json文件中的数据取出来,以便待会写入
            //代表每一条记录
            var obj = {     ----------------------待写入的数据
                img: img,
                url: url,
                title: title,
                id: guidGenerate(), ---------------------数据的id
                time: new Date()    ---------------------时间戳
            };
            arr.splice(0, 0, obj);  ------------------------在arr数组中插入数据
            //2)写入文件
            var newData = JSON.stringify(arr);
            fs.writeFile(filePath, newData, function(err){  -------------------------将newData写入filePath对应的文件
                if(err){    -----------------如果写入文件失败
                    return res.send({   --------------------返回错误状态信息
                        status:0,
                        info: '写入文件失败'
                    });
                }
                return res.send({   ------------------------如果成功,返回正确状态信息
                    status:1,
                    info: obj
                });
            });
        });
    });

测试一下,这个接口是否正确

  $.ajax({
       type: 'POST',
       url: '/data/write',
       data: {
            type: 'it',
            title: '测试标题',
            url: 'www.xxx.com',
            img: 'www.xxx.com/images/xxx.png'
       },
       success: function(data){
           if(data.status){
               alert('添加数据成功');
           }else{
               alert('添加失败');
           }
       },
       error: function(){
           alert('添加失败');
       },
       dataType: 'json'
  });

打开public/data/it.json,会发现多了一条数据,说明数据输入接口是ok的

it.json
  [
    {
      "img": "www.xxx.com",
      "url": "www.xxx.com/images/xxx.png",
      "title": "测试标题",
      "id": "25478B43-C814-4499-9AF5-2BB010F98099",
      "time": "2016-11-24T14:17:23.659Z"
    }
  ]

至此,一个简单的后台接口就完成了

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,547评论 6 477
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,399评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,428评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,599评论 1 274
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,612评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,577评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,941评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,603评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,852评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,605评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,693评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,375评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,955评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,936评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,172评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 43,970评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,414评论 2 342

推荐阅读更多精彩内容