初步尝试一步一步建立Web世界。

初步尝试Express&jade快速建站

最近一直在看Web开发相关的书籍,一周时间读完了《Node开发指南》一书,由于之前了解过一些Node的相关知识,于是前面基础知识学得比较快,到开发实践这一章的时候,却发现好多内容不能跟着练习了。因为近几年Node的发展过于快速,其Web开发框架Express必然也更新得比较频繁,并且版本与版本之间差异较大。所以,书中必然有好多代码在现在来看肯定运行不了,但是大体的框架还是在那里,想动手实践还是得对照着官方文档进行。

1. 生成Express项目

根据官方文档入门的介绍,根据Express建站的步骤大致写一下:

  1. npm install express 安装express
  2. npm install express-generator -g 安装express应用生成器
  3. express myapp 生成express项目目录以及基本启动代码
  4. DEBUG=myapp npm start 启动应用(Mac or Linux);set DEBUG=myapp & npm start 启动应用(Windows)
  5. 浏览器访问http://localhost:3000

通过上面几步很快就完成了一个项目的部署,那么接下来就是要往里填写内容了,用框架开发就是这么快,但是会忽略掉很多重要的细节。

打开myapp文件夹,会看到该项目的目录结构如下:

.
├── app.js
├── bin
│   └── www
├── package.json
├── public
│   ├── images
│   ├── javascripts
│   └── stylesheets
│       └── style.css
├── routes
│   ├── index.js
│   └── users.js
└── views
    ├── error.jade
    ├── index.jade
    └── layout.jade

了解过一些Node的相关知识就知道,Node是通过动态网页的方式来实现网站的,就如同其他语言Java、PHP一样,要实现动态页面就要在HTML模板中插入程序代码,于是就有了JSP、PHP以及ASP等技术。通过JavaScript实现的模板引擎有很多,Jade就是其中之一,为什么选择它,因为Express默认就是它,反正也是新接触,那就它咯。

2. Jade模板引擎

由于新学,也没有什么经验可谈,基本用法参考官网就可以了。这类语言基本上看一遍就百分之八九十了,接下来就是熟练使用它。

3. 回头看看app.js

// view engine setup
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'jade');

这里就是设置Jade模板引擎以及视图目录的地方。

4. 编写路由规则

编写路由规则,打开routes/index.js文件,添加4条路由规则,代表4个不同的页面。

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

/* GET detail page. */
router.get('/detail/:id', function(req, res, next) {
  res.render('detail', { title: 'Detail Page'});
});

/* GET admin page. */
router.get('/admin', function(req, res, next) {
  res.render('admin', { title: 'Admin Page'});
});

/* GET list page. */
router.get('/list', function(req, res, next) {
  res.render('list', { title: 'List Page'});
});

5. 瞧瞧jade模板视图文件

打开views/layout.jade

doctype html
html
  head
    title= title
    link(rel='stylesheet', href='/stylesheets/style.css')
  body
    block content

看了一遍jade语法的基本就能看出这是一个基本页面,然后再打开views/index.jade

extends layout
block content
  h1= title
  p Welcome to #{title}

路由规则中,title变量就用与此处,如此即为动态页面。npm start启动应用,访问http://localhost:3000得到页面如下图。

6. 依次创建detaillistadmin页面

根据路由规则所规定的访问路径,依次访问,会得到不同的动态页面。

转载保存:建站 | LP's Blog

初步使用bootstrap快速创建页面

初步尝试使用Express搭建了一个Web框架,那么接下来就是要在该框架下写上自己的页面,快速创建页面这里选择了bootstrap前端框架,通过它即使你不太懂前端设计,写出来的页面也不会太难看。

1. 安装bower前端包管理器

bower是一个前端软件包管理器,便于安装、更新以及卸载javascript,css,html等框架资源,并解决之间的相互依赖关系。

npm install -g bower   // 安装
bower help   // 查看帮助

这里YY一下:

npm是node.js的包管理器,通过它安装了expressexpress-generatorsupervisorbower等等软件,bower又是前端框架的软件包,安装了bootstrap以及jquery等一些依赖包。突然发现简直是包包相扣啊,渐渐的醉了。其中的水实在是太深了,想简单学个web开发也不是那么容易的事啊,有种淡淡的忧伤。然并卵,心向往之,一如既往。

2. 安装bootstrap以及jquery

当然你也可以直接将bootstrap以及jquery下载下来,放入项目文档中,不用安装什么包管理器,自己解决简单的依赖关系就OK了,但是不都是为了快速建站嘛,装个包管理器自动解决依赖关系。并且在发布自己的项目的时候,也不需要将所有的框架包一块发布,而只需将相关的json文件放到项目里就可以了,别人一目了然你的依赖关系,便于快速搭建。

有了bower,直接bower install bootstrap就OK了,因为依赖关系,它会自动给你装上jquery,完事。

3. 模板引擎中引入bootstrap以及jquery

安装好了或者说项目中已经放置好了bootstrapjquery之后,接下来就是在文件中引用它,在views文件夹中创建一个head.jade文件,顾名思义就是放置HTML中head标签里面的一些内容。如下代码:

link(href='/bootstrap/dist/css/bootstrap.min.css',rel='stylesheet')
script(src='/jquery/dist/jquery.min.js')
script(src='/bootstrap/dist/js/bootstrap.min.js')

创建完head.jade后,接下来在所有需要的页面中,加上include head.jade包含到页面中就OK了。

4. 使用模版布局

由于基本上所有的页面都需要包含head.jade,总不能每个页面都写上include head.jade 吧,于是布局文档layout.jade就要起作用了。单独创建layout.jade文件,将一些共性的代码写进去。

doctype html
html
  head
    title= title
    link(rel='stylesheet', href='/stylesheets/style.css')
    include ./includes/head
  body
    include ./includes/header
    h1= title
    block content

如上,一些独立的模块依然可以通过include语句进行加载,最后一句block content就是模版布局的关键,意思就是在模版的此处插入页面,也就是应用此模版布局的差异处。

然后在应用此模版布局的页面中,加上extent layout就OK了。如下:

extends ../layout
block content
  p Welcome to #{title}

注意:extends模版文件以及include代码中使用文件尽量使用相对路径。

5. 开始编辑页面

准备工作都做得差不多了,那么接下来就是使用jade语法以及bootstrap样式来编辑页面了。下面简单大致写个首页(index)以及详情页(detail)。

// index.jade
extends ../layout

block content
  .container
    .row
      h1= title
        small 图书列表
      each item in books
        .col-md-3.col-xm-6
          .thumbnail.text-center
            a(href='/books/#{item._id}')
              img(src='#{item.poster}',alt='#{item.title}')
            .caption
              h3= item.title
              .btn-group
                a.btn.btn-primary(href='/books/#{item._id}') 查看详情
                a.btn.btn-primary(href='#{item.buyUrl}') 购买书籍

// detail.jade
extends ../layout

block content
  .container
    .row
      h1= title
        small= book_title
      .col-md-9.col-sm-9
        .thumbnail
          img(src='#{book_poster}')
          .caption
            p= book_info
            a.btn.btn-primary(href='#{book_buyUrl}') 购买书籍
      .col-md-3.col-sm-3
        h3 作者
        p #{book_author}
        h3 出版年月
        p #{book_year}年
        h3 页数
        p #{book_pages}页
        h3 定价
        p ¥#{book_price}

上面两个页面是bootstrap里最基本的布局,想详细学习bootstrap推荐Bootstrap 教程 | 菜鸟教程

建站 | LP's Blog

初步使用Node连接Mysql数据库

使用Node做Web页面开发,基本上是连接非关系型数据库mongodb,而这里我还是先尝试连接了一下mysql数据库,因为相对于mysql来说mongodb过于生疏,想着快速出来页面,所以选择相对熟悉一些的mysql

1. 安装mysql

下载MySQL :: MySQL Downloads,并进行安装。安装完,会引导你对数据库进行配置,设置root密码以及创建普通用户以及密码。

2. 安装Node-mysql

通过npm安装mysql的软件包,通过它方便快速调用函数连接mysql数据库。进入项目文件夹,执行npm install mysql --save就行了。

安装完,在项目文件夹的node_modules目录下会生成mysql的目录。

3. 查看readme文档

进入mysql目录中,查看README文档,这步很重要,不要到处百度Google搜索怎么用,因为由于版本的不一样,也许你得到的答案并不能使你成功连接数据库。毕竟Node发展如此之快。

如果你认真读了README文档,接下来的步骤就不用再看了,避免由于版本不一致而误导你。

4. 连接mysql数据库

进入项目文档,新建TestMysql.js示例,编写如下代码:

var mysql      = require('mysql');
var connection = mysql.createConnection({
  host     : 'localhost',
  user     : 'me',
  password : 'secret',
  database : 'my_db'
});

connection.connect();

connection.query('SELECT 1 + 1 AS solution', function(err, rows, fields) {
  if (err) throw err;

  console.log('The solution is: ', rows[0].solution);
});

connection.end();
  • 连接基本参数

    • host 主机名,localhost代表本地
    • user Mysql用户
    • password 密码
    • database 连接的数据库
  • client.connect()连接数据库

  • client.query()执行SQL语句
  • client.end()关闭连接。

然后通过node TestMysql.js执行程序,确保你在执行之前已经启动了Mysql服务。

5. 增删改查

使用数据库无外乎增删改查,下面示例可能会对你有些帮助。

var mysql      = require('mysql');
var connection = mysql.createConnection({
  host     : 'localhost',
  user     : 'me',
  password : 'secret',
  database : 'my_db'
});

connection.connect();

// 增加记录
client.query('insert into test (username ,password) values ("lupeng" , "123456")');

// 删除记录
client.query('delete from test where username = "lupeng"');

// 修改记录
client.query('update test set username = "pengloo53" where username = "lupeng"');

// 查询记录
client.query("select * from test" , function selectTable(err, rows, fields){
  if (err){
    throw err;
  }
  if (rows){
    for(var i = 0 ; i < rows.length ; i++){
      console.log("%d\t%s\t%s", rows[i].id,rows[i].username,rows[i].password);
    }
  }
});

connection.end();

到此,Mysql数据库的初步连接就告一段落了,接下来就可以在Node项目中自行发挥了。

转载保存:建站 | LP's Blog

初步使用Express+Mysql异步读取数据展示页面

通过之前3步的初步学习,学会了如何使用jade模版编写动态页面,同时也学会了如何使用mysql数据库。今天实现一个简单的例子,结合expressmysql,从数据库中取出数据,最后在前台页面展示出来。 下面进入正题,通过Express+Mysql实现异步读取数据并展示在页面中,分为下面几步:

1. 建立数据访问对象文件

也就是常说的DAO(data access object),在项目目录中,新建db文件夹,放访问数据库的相关文件,在db目录中新建db.js,其中代码如下:

var mysql = require('mysql');

var options = {
  host: 'localhost',
  user: 'lupeng',
  password: '080910',
  database: 'myapp'
}

exports.createConn = function (){
  var client = mysql.createConnection(options);
  return client;
}

exports.getUsers = function (client,callback){
  var selectstatement = 'select * from user';
  client.query(selectstatement, function(errs,rows,fields){
      if (errs){
        callback(errs);
      }
      if (rows){
        console.log(rows);
        callback(rows);
    }
  });  
}

基本上是标准的一套代码,连接数据库方法,查询数据方法,当然实现更复杂的功能,会利用到数据池以及更多SQL。

上述代码简单实现了两个方法,一个是获取数据库对象createConn,一个是获取用户的方法getUsers注意得到数据库数据后,作为参数赋予回调函数callback。

2. 编辑路由方法

当访问到某个路径的时候,查询数据库,并返回结果,最终通过res对象将内容发送到客户端上。app.js中编写路由方法如下:

var db = require('../db.js');
// ... 省略
app.get('/',function(req,res){
  var client = db.createConn();
  db.getUsers(client,function(results){
    if(results){
      res.render('index',{results: results});
    }
  });
});

首先调用createConn方法获取数据库对象client,然后调用getUsers方法取得数据,实现回调函数,将数据回传回来,最后通过res对象发送至前台页面。

3. view模版

res对象渲染index页面,最终显示在前端。这里使用的是jade模版引擎,下面看看index.jade示例代码:

doctype html
html
  head
    title= title
    link(href='/bootstrap.min.css',rel='stylesheet')
  body
    .container
      .row
        h1 读取用户数据库
          small Mysql
        .table-responsive
            table.table
              thead
                tr
                  th ID
                  th 用户名
                  th 密码
                tbody
                  each item in results
                    tr
                      td= item.id
                      td= item.username
                      td= item.password

前台显示如下图,一个打印了数据库数据的简单页面。

当然前提要在数据库中新建一个myapp的数据库,在myapp中新建user表。

总结

  1. 异步读取数据库内容后,将数据作为参数赋予回调函数;
  2. 路由模块中通过实现回调函数获取数据库数据,最终显示在前台页面;

转载保存:建站 | LP's Blog

Node实现todo-list来理解HTTP的方法

在Web编程中,最常用的HTTP方法有GET,POST,DELETE,PUT,这些标准的HTTP方法构成了WEB应用程序中一套基本的RESTful原则。

这里通过Node最简单HTTP模块来实现一个完整的todo-list命令行程序,也就是常说的CLI(command-line interface),通过它了解一下HTTP中最基本的方法。

服务器与客户端的交互不通过浏览器实现,而通过最纯粹的命令行工具curl来实现,使其方法更加透明而便于理解。减少中间写HTML代码的环节。

cURL - Download从这个界面下载,*nix系统基本上都自带有,Windows用户需要下载该命令行工具。

接触Node首先就是使用HTTP模块写出打印Hello,world的服务器,这才是真正意义上Node的Hello,world,代码如下:

var http = require('http');
http.createServer(function (req,res){
  res.writeHead(200 , {"Content-Type" : "text/html"});
  res.end('Hello,world');
}).listen(9000);
console.log("Your server is started @ http://localhost:9000");

使用浏览器访问http://localhost:9000就可以打印出Hello,world

下面todo-list的例子,通过对req.method请求方法的判断,对服务器发起HTTP的POSTDELETEGET等基本方法。代码如下:

var http = require('http');
var url = require('url')
var items = [];
http.createServer(function(req,res) {
  switch (req.method){
    case 'POST':
      var item = '';
      req.setEncoding('utf8');
      req.on('data', function(chunk){
        item += chunk;
      });
      req.on('end',function(){
        items.push(item);
        res.end('add success!\n','utf8');
      });
      break;
    case 'GET':
      for (var i =0 ; i < items.length ; i ++){
        res.write(i + ') ' + items[i] + '\n','utf8');
      }
      res.end();
      break;
    case 'DELETE':
      var pathname = url.parse(req.url).pathname;
      var i = parseInt(pathname.slice(1) , 10);
      if (isNaN(i)){
        res.statusCode = 400;
        res.end('Invalid item id!\n');
      }else if (!items[i]){
        res.statusCode = 404;
        res.end('Item not found!\n');
      }else{
        items.splice(i , 1);
        res.end('delete success!\n');
      }
      break;
  }
}).listen(9000);
console.log('Your server is started @9000');

上面代码显示了POST请求的处理方法,以及Delete Item的时候,对防错的一些处理方法。对程序的健壮性有一定的保障。当然功能上还是非常弱的。

将上面代码保存为app.js,启动服务器:node app.js

  • 输入curl -d "read book" http://localhost:9000发起POST请求,添加一条item;
  • 输入curl http://localhost:9000发起GET请求,获取item列表;
  • 输入curl -X DELETE http://localhost:9000/0删除第0条item。

OK了,自己尝试一下吧。

Node实现最简单的todo-list页面

上一篇是通过curl命令行工具实现的一个简单的todo-list CLI程序,但是没有页面总归是不够自然,这里就添加上简单的HTML页面,然后同样实现那个简单的todo-list功能页面。通过浏览器来感受一下Node Web的魅力。

var http = require('http');
var qs = require('querystring');
var items = [];

var server = http.createServer(function(req,res){
  if('/' == req.url){
    switch(req.method){
      case 'GET':
        show(res);
        break;
      case 'POST':
        add(req,res);
        break;
      default:
        badReq(res);
    }
  }else{
    noFound(res);
  }
});

添加一个req.url访问路径的限制,然后指定GET请求以及POST请求对应的方法。当服务器接收到GET请求时,执行show()方法;当服务器收到POST请求时,执行add()方法。同时为了程序的健壮性,填加了相关错误处理的方法,分别为响应失败以及404 Not Found处理方法。

下面主要实现show()方法以及add()方法就行了。

function add(req,res){
  var body = '';
  req.on('data',function (chunk) {
    body += chunk;
  });
  req.on('end',function(){
    var list = qs.parse(body);
    items.push(list.name);
    show(res);
  });
}

先看下add()方法,因为不涉及到页面,所以此处代码基本没有什么变化,只是在添加完成后,直接执行show()方法显示出来。下面再来看看show()方法。

function show(res){
  var item = '';
  var pageContent1 = '<html><head><title>Todo List</title></head><body>'
    + '<h1> Todo List </h1>'
    + '<ol>';
  var pageContent2 = '';
  for (var i = 0; i < items.length; i++) {
    pageContent2 += '<li>' + items[i] + '</li>';
  };
  var pageContent3 = '</ol>'
    + '<form method="POST" action="/">'
    + '<input type="text" name="name"><br/>'
    + '<input type="submit" value="add a list"><br/>'
    + '</form>';
  var pageContent = pageContent1 + pageContent2 + pageContent3;
  res.setHeader("content-type","text/html");
  res.end(pageContent);
}

最原始的显示页面的方法,将HTML代码直接写进逻辑中,虽然不建议这么干,但是还有比这更直观的吗?将HTML直接通过res对象返回到客户端。

当然还有两个方法badReq()noFound(),实现如下:

function badReq(res){
  res.statusCode = 500;
  res.end('Bad Request!');
}
function noFound(res){
  res.statusCode = 404;
  res.end('Not Found!');
}

OK了,保存文件为app.js,然后node app.js启动它,在浏览器中输入http://localhost:9000看下效果吧。通常情况下,浏览器只发送GETPOST请求,想实现删除的功能,可以借助URL来实现或者通过Ajax都是可行的。这里给出了通过URL来实现的方法,想要删除第一条,使用http://localhost:9000/del/1试试。