基于Express搭建开发环境

对于一个前端开发人员来说,node.js可以说是开发后端的福音。本人毕设项目使用的是asp.net(只是使用ashx来接收前端的ajax,并没有使用那些恶心的控件),通过对比发现整个项目都使用js实在是幸福。

Node.js

关于node.js的优点就不再多说,网上一搜一大堆,项目也可以找到很多。这里主要说一下node.js关于搭建web应用这一块的缺点。
众所周知,node.js需要自己搭建服务器,也就是说你需要自己监听一个端口并启动它

var http=require('http');
http.createServer(function(req,res) {
    res.writeHead(200, {'Content-Type': 'text/plain'});
    res.write("hello sunnychuan");
    res.end();
}).listen(3000);
console.log("server is running!");

这里有一本电子书帮助你使用原生的node.js搭建web应用,点击这里

不仅仅是监听端口,我们往往会根据用户输入的url从本地找到相应文件并将它写回请求

fs.exists(filePath,function(exists){
    if(exists){
       res.writeHead(200,{'Content-Type':contentType});
       var stream=fs.createReadStream(filePath);
       stream.on('error',function(){
          res.writeHead(500,{'Content-Type':'text/html'});
          res.end('<h1>500 Server Error</h1>');
       });
       stream.pipe(res);
    }
}

我们还会针对前端的ajax请求做路由处理

//根据不同的路径调用不同的处理程序
var handle={};
handle["/api/get.json"]=requestHandlers.get;
handle["/api/post.json"]=requestHandlers.post;
function route(handle,pathname,req,res){
    if(typeof handle[pathname]==='function'){
        handle[pathname](req,res);
    }
    else{
        res.writeHead(404,{'Content-Type':'text/html'});
        res.write('<h1>404 Not Found</h1>');
        res.end();
    }
}
var pathname=decodeURI(url.parse(req.url).pathname);
if(path.extname(pathname)=='.json'){
    route(handle,pathname,req,res);
}

通过上面那么一折腾,原本的热情就消退了一半,这里我推荐一下express框架,官方文档在这里

Express

安装和目录结构

首先安装express

npm install express --save-dev

安装express的应用生成器

npm install express-generator -g

使用它的应用生成器可以很快建立一个项目

express myapp

然后进入到该文件夹下,安装所有依赖

cd myapp
npm install

你的目录结构长这个样子

bin是启动项,在bin/www里面你可以修改端口号
node_modules用来存放npm安装的模块
public里面用来存放资源
routes是路由控制,存放了所有的处理程序
views是视图文件,相当于html页,在routes中会使用类似

router.get('/', function(req, res, next) {
  res.render('index', { title: 'Express' });
});

这样的代码来替换模板引擎里的内容,有点像java的.jsp文件和asp.net的.asp文件
app.js用来配置express,你可以在这里进行路由分配和错误处理并按需加载中间件

启动项目

npm start

修改代码

作为前端开发的你,也许会厌恶由后端直接将数据渲染在页面上(至少我是这样),我们通常使用ajax来进行前后端交互并自行处理后端的数据,因此整个views文件就可以直接delete掉了。

step1 更改目录结构
把public更名为client,新建server文件夹并把routes和app.js放到里面(views直接删除即可),这样一来整个项目结构就比较明显了,客户端和服务端分离。

step2 修改routes文件夹
routes里默认有index.js和users.js两个路由文件,其中index.js是负责模板渲染的

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

/* GET home page. */
router.get('/', function(req, res, next) {
  res.render('index', { title: 'Express' });
});

module.exports = router;

而users.js是直接返回一个字符串

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

/* GET users listing. */
router.get('/', function(req, res, next) {
  res.send('respond with a resource');
});

module.exports = router;

既然我们删掉了views,那么index.js的代码肯定要修改的。我删掉了这两个文件,并新建了get.js和post.js文件用来接收和处理前端的ajax请求

//get.js
module.exports=function(req,res){
  console.log(req.query.userName);
  res.json({code:200,data:"this is a get request"});
}
//post.js
module.exports=function(req,res){
    console.log(req.body.userName);
    console.log(req.body.password);
    res.json({code:200,data:"this is a post request"});
}

另外,我还新建了一个名为router.js的文件,用来分配路由(默认是在app.js文件中进行路由分配的,但是一旦请求过多,app.js会十分冗长)

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

var get=require('./get');
var post=require('./post');

router.get('/get.json',get);
router.post('/post.json',post);
module.exports=router;

step3 修改app.js
对模块加载做如下修改

//修改前
var index = require('./routes/index');
var users = require('./routes/users');
//修改后
var router=require('./routes/router.js');

删掉视图引擎的设置

//删除下面的代码
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'jade');

对静态资源的加载做一些更改,默认是在"public"文件夹下读取并加载静态资源的,现在我们设置为先从根路径读取文件,如果不存在则从"client"中读取文件

//修改前
app.use(express.static(path.join(__dirname, 'public')));
//修改后
var rootDir=path.resolve(__dirname);
var projectDir=path.resolve(__dirname,'../','client');
app.use(express.static(rootDir));
app.use(express.static(projectDir));

替换默认的路由加载,改为上面require的router。/api是一个虚拟路径,这样每当我们访问/api/xxx.json就会通过路由来分配不同的控制器完成业务逻辑

//修改前
app.use('/', index);
app.use('/users', users);
//修改后
app.use('/api',router);

我们还需要让根路径加载首页面

app.get('/', function(req, res){
  res.sendFile(projectDir+'/index.html');
});

由于不需要渲染视图,因此错误页面的处理也要进行修改,我这里仅仅是把错误信息返回给前端

//修改前
app.use(function(err, req, res, next) {
  res.locals.message = err.message;
  res.locals.error = req.app.get('env') === 'development' ? err : {};
  res.status(err.status || 500);
  res.render('error');
});
//修改后
app.use(function(err, req, res, next) {
  res.locals.message = err.message;
  res.locals.error = req.app.get('env') === 'development' ? err : {};
  res.status(err.status || 500);
  res.json({code:500,msg:"error"});
});

测试

我们需要编写前端代码进行测试,这里我使用angular简单地发送get和post请求

angular.module("indexApp",[])
.controller("IndexCtrl",function($scope,$http){
    $scope.get=function(){
        $http({
            method:"get",
            url:"/api/get.json",
            params:{userName:"sunnychuan"}
        }).then(function(res){
            if(res.data.code==200){
                console.log(res.data.data);
            }
            else if(res.data.code==500){
                console.log(res.data.msg);
            }
        })
    }
    $scope.post=function(){
        $http({
            method:"post",
            url:"/api/post.json",
            data:{userName:"sunnychuan",password:"qc"}
        }).then(function(res){
            if(res.data.code==200){
                console.log(res.data.data);
            }
            else if(res.data.code==500){
                console.log(res.data.msg);
            }
        })
    }
})

同样的,使用npm start启动项目,在url中输入localhost:3000

点击get按钮

点击post按钮


至此,基本的环境搭建成功,搭配mongodb会在之后的文章中介绍。

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

推荐阅读更多精彩内容