基于node的前后端分离初识
久闻node的大名,先后也看过node的文档,但是,总是碍于没有挑起我的G点,所以实际codeing的例子都没有。最近,突然很有兴致,想把原有用页面ajax渲染的页面采用服务端node来渲染,研究了两天终于有点眉目了。
先来按我的理解来解释一遍node,node是服务端语言,只是用的JavaScript,所以非常适合前端的工程师去研究这个后端语言,node本身就能够实现整个站点或者服务的全部。从页面渲染到数据存储,如同php和javaweb等其他web开发一样,而且node很适合并发量大的访问服务,至于具体的原因,还是问度娘比较好。
但是,今天我说的这件事情,仅仅是为了前后端分离。所以我们没有必要处理具体的业务逻辑,因为前端的职责本就是html和js,css,所有的工作就为了页面的渲染和交互。所以,这里我们仅仅只用node去帮助我们获取接口数据,然后利用模板渲染成html就好。
先来说下这样做与之前ajax获取接口数据渲染有什么不同,我们可以先来看下ajax方式渲染的源码,打开之前的项目

这是一个新闻列表,我们可以打开源码看看内部dom,注意是打开源码。

我们看到了,新闻列表内其实只有一个容器,并没有新闻列表的内容。这种方式其实就是在ajax获取到数据之后,动态的插入dom中。
我们再来看node的方式渲染的页面。同样是一个新闻列表页。

其实,这里的调用的是同一个javaAPI,所以内容是一样的,这一次我们打开源码看看与之前有什么不一样的地方。

很明显,这一次我们的新闻列表,是直接html渲染好的。这里面的妙处,自然不言而喻,其他的不说,对于seo自然是友好的不行啊,其次是首屏体验,这种方式渲染的页面是没有白屏时间的,ajax在获取数据之前,白屏时间还是能够感受到的。
说了这么多,我们正式进入正题,现有前后端分离,后端一般只提供api,也就是数据,后端工程师大哥是很不想去套你的html模板的。因为他们不知道怎么样去闭合标签哦,更不想去改你的CSS了,js那就更不用多说了。所以后端的大哥负责提供接口是个明智的合作方式,至于页面怎么显示,交互的js怎么写,还是交给前端比较靠谱。
但是,那又有人会说,为什么前端不能去写写jsp呢?我想说的是,后端的那个java环境,前端的同学想去搭吗?就算会搭环境,会写jsp,而且本身就会后端开发,但是前后端联调的时候要傻眼了吧。所以说,这种事情还是分开的比较好,不仅效率高,而且术业专攻,大家心里都爽的不行不行的。
那么,现在我们就来动手搞起我们的node服务吧,首先node环境是要有的,node安装很简单,去node官网看看就会了。其次就是个要有个编辑器,本人用的是hbuiler,需要集成node开发插件,需要一点耐心。
好,工具准备好了,动手就快了,首先新建一个node项目,选择Express模板。

再选择ejs模板页面,点击完成后就是以个完整的项目了,运行app.js就可以启动服务了。

在浏览器中打开127.0.0.1:3000就能访问index页面了。
好,现在我们有了才正式开始动手写代码,打开index.js,只有一个输出语句,这里是数处理请求的方式,我们要把之前需要在ajax中调用接口再这里调用就好了,拿到接口数据,请求接口的方法很简单,用http模块的request方法:
exports.index = function(req, res){
    var page = req.params.page||1;
    if(isNaN(parseInt(page))){
        page=parseInt(1);
    }
    if(page<1){
        page=1;
    }
    page = parseInt(page);
    console.log(page);
    var http = require('http');
    //http://120.27.137.16/wangda/news/queryAll.action?page=1&rows=10
    // 用于请求的选项
    var options = {
       host: 'szwdtx.cn',
       port: '80',
       path: '/wangda/news/queryAll.action?page='+page+'&rows=10'
    };
    // 处理响应的回调函数
    var callback = function(response){
        response.setEncoding('utf8');
       // 不断更新数据
       var body = '';
       response.on('data', function(data) {
          body += data;
       });
       response.on('end', function() {
          // 数据接收完成
          console.log(body);
          var next = page+1;
          var data = JSON.parse(body);
          if(page >= Math.ceil(data.total/10)){
              //page = Math.ceil(data.total/10);
              page = Math.ceil(data.total/10);
              next = page;
          }
          res.render('index', { title: '旺达资讯',data:data,page:{page:page,all:Math.ceil(data.total/10),prve:page-1,next:next}});
       });
    };
    // 向服务端发送请求
    var req = http.request(options,callback);
    req.end();
};
其实和ajax调用的接口的方式很像,然后我们只需要在response.on('end', function() {})中将数据交给idnex.ejs模板渲染就ok了。
<!DOCTYPE html>
<html>
  <head>
    <title><%= title %></title>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0" />
    <link rel='stylesheet' href='/stylesheets/style.css' />
  </head>
  <body>
    <h1 style="text-align: center;"><%= title %></h1>
    <ul>
        <%for(var i = 0; i < data.rows.length; i++){%>
            <li>
                <img src="<%=data.rows[i].img%>" style="width:200px;"/>
                <p><a href="/news/<%=data.rows[i].id%>"><%=data.rows[i].title%></a></p>
            </li>
        <%}%>
    </ul>
     <p style="text-align: center;"><a href="/<%=page.prve%>">上一页</a><%=page.page%>/<%= page.all %><a href="/<%=page.next%>">下一页</a></p>
  </body>
</html>
ejs模板和html很接近,上手会非常快。现在我们在看看入口文件app.js中需要做些什么?
/**
 * Module dependencies.
 */
var express = require('express')
  , routes = require('./routes')
  , user = require('./routes/user')
  , news = require('./routes/news')
  , http = require('http')
  , path = require('path');
var app = express();
// all environments
app.set('port', process.env.PORT || 3000);
app.set('views', __dirname + '/views');
app.set('view engine', 'ejs');
app.use(express.favicon());
app.use(express.logger('dev'));
app.use(express.bodyParser());
app.use(express.methodOverride());
app.use(app.router);
app.use(express.static(path.join(__dirname, 'public')));
// development only
if ('development' == app.get('env')) {
  app.use(express.errorHandler());
}
app.get('/', routes.index);
app.get('/:page', routes.index);
app.get('/users', user.list);
app.get('/news/:id',news.getnews);
http.createServer(app).listen(app.get('port'), function(){
  console.log('Express server listening on port ' + app.get('port'));
});
其实我们,只需要做一下分页就ok,app.get('/:page', routes.index);这样就可以实现访问不带参数和带pege参数的页面都跳转到index页面,如果不带page参数,就默认是第一页,带参数就返回当前页。
运行app.js就能显示新闻列表了,见上面的图3
项目git地址:http://git.oschina.net/zss01/node
基于node的前后端分离初识的更多相关文章
- (转)也谈基于NodeJS的全栈式开发(基于NodeJS的前后端分离)
		
原文链接:http://ued.taobao.org/blog/2014/04/full-stack-development-with-nodejs/ 随着不同终端(pad/mobile/pc)的兴起 ...
 - 也谈基于NodeJS的全栈式开发(基于NodeJS的前后端分离)
		
前言 为了解决传统Web开发模式带来的各种问题,我们进行了许多尝试,但由于前/后端的物理鸿沟,尝试的方案都大同小异.痛定思痛,今天我们重新思考了“前后端”的定义,引入前端同学都熟悉的NodeJS,试图 ...
 - 基于NodeJS进行前后端分离
		
1.什么是前后端分离 传统的SPA模式:所有用到的展现数据都是后端通过异步接口(AJAX/JSONP)的方式提供的,前端只管展现. 从某种意义上来说,SPA确实做到了前后端分离,但这种方式存在两个问题 ...
 - 基于NodeJS的全栈式开发(基于NodeJS的前后端分离)
		
也谈基于NodeJS的全栈式开发(基于NodeJS的前后端分离) 前言 为了解决传统Web开发模式带来的各种问题,我们进行了许多尝试,但由于前/后端的物理鸿沟,尝试的方案都大同小异.痛定思痛,今天我们 ...
 - 基于 koajs 的前后端分离实践
		
一.什么是前后端分离? 前后端分离的概念和优势在这里不再赘述,有兴趣的同学可以看各个前辈们一系列总结和讨论: 系列文章:前后端分离的思考与实践(1-6) slider: 淘宝前后端分离实践 知乎提问: ...
 - [转] 基于NodeJS的前后端分离的思考与实践(五)多终端适配
		
前言 近年来各站点基于 Web 的多终端适配进行得如火如荼,行业间也发展出依赖各种技术的解决方案.有如基于浏览器原生 CSS3 Media Query 的响应式设计.基于云端智能重排的「云适配」方案等 ...
 - 【SpringSecurity系列2】基于SpringSecurity实现前后端分离无状态Rest API的权限控制原理分析
		
源码传送门: https://github.com/ningzuoxin/zxning-springsecurity-demos/tree/master/01-springsecurity-state ...
 - vue+node+mongodb前后端分离博客系统
		
感悟 历时两个多月,终于利用工作之余完成了这个项目的1.0版本,为什么要写这个项目?其实基于vuejs+nodejs构建的开源博客系统有很多,但是大多数不支持服务端渲染,也不支持动态标题,只是做到了前 ...
 - 基于Vue的前后端分离项目实践
		
一.为什么需要前后端分离 1.1什么是前后端分离 前后端分离这个词刚在毕业(15年)那会就听说过,但是直到17年前都没有接触过前后端分离的项目.怎么理解前后端分离?直观的感觉就是前后端分开去做,即功 ...
 
随机推荐
- linux----查看系统版本命令
			
uname -a 可显示电脑以及操作系统的相关信息 cat /proc/version 说明正在运行的内核版本 cat /etc/issue 显示的是发行版本信息
 - UVA - 12230 Crossing Rivers(过河)(期望)
			
题意:从A到B需要经过n条河,已知AB间距离D和每条河的长度L以及在该条河上的船速v,求A到B平均情况下需多长时间.陆地行走速度为1,船的位置和朝向均匀随机. 分析: 1.过一条河,最短时间L/v(无 ...
 - windows driver 枚举串口
			
//枚举串口 NTSTATUS status; HANDLE hKey = NULL; OBJECT_ATTRIBUTES oa; UNICODE_STRING strPath = RTL_CONST ...
 - Maven:java.lang.RuntimeException: Unexpected error: java.security.InvalidAlgorithmParameterException: the trustAnchors parameter must be non-empty
			
直接参考前面一篇文章中间介绍的第2种方法即可:Maven:sun.security.validator.ValidatorException: PKIX path building failed: s ...
 - JVM探秘:jinfo查看JVM运行时参数
			
本系列笔记主要基于<深入理解Java虚拟机:JVM高级特性与最佳实践 第2版>,是这本书的读书笔记. 如何查看JVM运行时参数,对于线上JVM调优是很关键的,因为只有知道了当前使用的JVM ...
 - Django中使用ORM
			
一.ORM概念 对象关系映射(Object Relational Mapping,简称ORM)模式是一种为了解决面向对象与关系数据库存在的互不匹配的现象的技术. 简单的说,ORM是通过使用描述对象和数 ...
 - LeetCode 124. Binary Tree Maximum Path Sum 二叉树中的最大路径和 (C++/Java)
			
题目: Given a non-empty binary tree, find the maximum path sum. For this problem, a path is defined as ...
 - Apache Spark:来自Facebook的60 TB +生产用例
			
本文主要讲Facebook扩展spark替换hive的过程中积累的经验和教训. 浪尖整理翻译https://databricks.com/blog/2016/08/31/apache-spark-sc ...
 - vue-cli3.x   搭建项目目
			
安装文档 https://cli.vuejs.org/zh/guide/ 安装条件 npm 更至最新 node >=8.9 可以用npm -v 查看npm的版本号 1.关于旧版本 Vue CLI ...
 - 实盘交易哪些代码BUG产生严重亏损
			
1.少写一个return,疯狂开平2900次,以爆仓结束 2.在上生产环境前,不小心误删除了一个“!”(我至今也不清楚为什么会误删了,晕),导致平仓逻辑一直不满足,不止损,让我损失惨重! 3.卖单变买 ...