一、前言

在"初探nodeJS"随笔中,我们对于node有了一个大致地了解,并在最后也通过一个示例,了解了如何快速地开启一个简单的服务器。

今儿,再次看了该篇随笔,发现该随笔理论知识稍多,适合初级入门node,固萌生一个想法--想在该篇随笔中,通过一步步编写一个稍大一点的node示例,让我们在整体上更加全面地了解node。

so,该篇随笔是建立在"初探nodeJS"之上的,固取名为"进阶之初探nodeJS"。

好了,侃了这多,那么我们即将实现一个什么样的示例呢?

示例说明,如下:

用户通过url之127.0.0.1/login进入登入页面,待用户输入账户名后(密码选项输不输都无所谓,只是为了页面合理),点击提交,进入home页面。

node服务端,怎么处理的呢?通过URL判断,当为/login时,服务端读取login.html的内容,并将其传递到前端显示;当为/home时,服务端读取home.html的内容,并将login.html中提交的账号名与home.html中的模板替换,最后将结果传递到前端显示。

大体流程,如下:

示例最终实现效果,如下:

好了,了解示例需求,下面我们就一起来一步一步实现上述Demo吧。

二、前端文件准备

要实现上述效果,我们首先简单地准备两个页面login.html、home.html以及一张贺岁图片,显而易见,供接下来node读取它们并将它们呈现到浏览器中,使用。

在上述说明中,已讲过node服务器是通过路由来判断,加载哪张页面,固我们将login.html中form的action写作'./home',以达到我们的目的,请求方式嘛,使用的当然是post咯。

且,因为我们要将在login.html中填写的账户名动态地与home.html结合,固home.html中的“称呼”位置,不能写死,因此我们利用{name}来占位,随后利用node动态替换。

好了,简易编写的login.html、home.html以及贺岁图,如下:

  1. <!DOCTYPE html>
  2. <head>
  3. <meta charset="utf-8">
  4. <style>
  5. form {
  6. text-align:center;
  7. }
  8. </style>
  9. </head>
  10. <body>
  11. <form action="./home" method="post">
  12. 账户:<input type="text" name="name"/><br/>
  13. 密码:<input type="password" name="password"/><br/>
  14. <input type="submit" value="提交"/>
  15. </form>
  16. </body>
  17. </html>

login.html

  1. <!DOCTYPE html>
  2. <head>
  3. <meta charset="utf-8">
  4. <style>
  5. body {
  6. text-align:center;
  7. }
  8. span {
  9. color: blue;
  10. }
  11. </style>
  12. </head>
  13. <body>
  14. <div>
  15. <span>{name}</span>,新de一年,一定要开心哦~
  16. </div>
  17. <img src="./getPic"/>
  18. </body>
  19. </html>

home.html

newYear.png

三、编写node服务

上述中,我们所需要的前端文件已经准备完毕,接下来就是通过node来编写服务,将它们串联起来咯。

首先,我们搭建一个主文件,取名为main.js吧,作用不言而喻,主入口嘛,如果我们在代码编写完毕后,想要启动服务,就node main.js就OK咯。

如下:

  1. 'use strict';
  2. var http = require('http');
  3. var server = http.createServer();
  4. server.on('request',function(req, res){
  5. //排除favicon.ico请求
  6. if(req.url != '/favicon.ico'){
  7. //TODO
  8. }else{
  9. res.end();
  10. };
  11. }).listen('80');
  12.  
  13. console.log('Server running!');

接着,我们就一起来逐步完善这个主文件。

在“前言”中我们提过,当一个请求来到服务中,我们采取获取URL的路径,来判断接下来的操作,已到达降低耦合性的目的。

所以,在主程序中,我们得利用url这个模块,来获得url中的相关路径,并通过正则来得到第一个路径名,通过接下来的路由模块,处理。

如下:

  1. 'use strict';
  2. var http = require('http');
  3. var url = require('url');
  4. var server = http.createServer();
  5. server.on('request',function(req, res){
  6. if(req.url != '/favicon.ico'){
  7. //获取路径
  8. let pathname = url.parse(req.url).pathname;
  9. pathname = pathname.match(/\w+/)[0];
  10. //router具体,待写...
  11. router[pathname](req, res);
  12. }else{
  13. res.end();
  14. };
  15. }).listen('80');
  16.  
  17. console.log('Server running!');

好了,接下来,我们就一起来编写router这个模块吧。

在我们示例中,router无外乎就是处理login、home以及图片请求getPic,所以,我们将router模块基本骨架,暂定如下:

  1. 'use strict';
  2. var router = {
  3. login: function(req, res){
  4. //TODO
  5. },
  6. home: function(req, res){
  7. //TODO
  8. },
  9. getPic: function(req, res){
  10. //TODO
  11. }
  12. };
  13. module.exports = router;

 且,我们发现login、home以及getPic这三个操作,有很多共通之处,如都会读取服务端本地文件,以及将读取的文件,写入响应体中,固我们将这些操作提取出来,作为operation模块。

在operation模块中,我们需要使用到node内置'fs'这个模块来读取文件,'fs'模块我们将会用到如下方法:

1、fs.readFileSync--同步读取文件

2、fs.readFile--异步读取文件

3、fs.writeFileSync--同步写入文件

4、fs.writeFile--异步写入文件

需要注意的是,读取图片也就使用的fs.readFileSync/fs.readFile,不过就是第二个参数还需加上'binary',二进制嘛。

  1. 'use strict';
  2. var fs = require('fs');
  3. var operationFile = {
  4. readFileSync: function(path, callback){//同步读取文件
  5. let data = fs.readFileSync(path, 'utf-8');
  6. syncOperation(callback, data, '同步读取文件完毕');
  7. },
  8. readFileAsync: function(path, callback){//异步读取文件
  9. fs.readFile(path, function(err, data){
  10. asyncOperation(err, callback, data, '异步读取文件成功');
  11. });
  12. },
  13. writeFileSync: function(path, data, callback){//同步写入文件
  14. fs.writeFileSync(path, data);
  15. syncOperation(callback, null, '同步写入文件完毕');
  16. },
  17. writeFile: function(path, data, callback){//异步写入文件
  18. fs.writeFile(path, data, function(err){
  19. asyncOperation(err, callback, null, '异步写入文件完毕');
  20. });
  21. },
  22. readImg: function(path, callback){//异步读取图片
  23. fs.readFile(path, 'binary', function(err, file){
  24. asyncOperation(err, callback, file, '异步读取图片完毕');
  25. });
  26. }
  27. };
  28. function syncOperation(callback, data, msg='操作成功'){
  29. if(typeof callback === 'function'){
  30. callback(data);
  31. }else{
  32. console.log(msg);
  33. }
  34. }
  35. function asyncOperation(err, callback, data, msg='操作成功'){
  36. if(err){
  37. console.log(err);
  38. }else if(typeof callback === 'function'){
  39. callback(data);
  40. }else{
  41. console.log(msg);
  42. }
  43. }
  44. module.exports = operationFile;

operation模块

另外,我们在login.html中提交表单时,使用到了post请求,那么在node服务中应该怎么接收传来的实体呢?

node是采用的监听'data'来接收post方法实体信息,通过'end'来监听接收信息完毕事件。

而,node接收get请求参数就没这么复杂,直接获取url后的查询字符串即可。

好了,我们将获取post、get请求参数,也写为一个模块,取名为getQuery,如下:

  1. 'use strict';
  2. var url = require('url');
  3. var querystring = require('querystring');
  4.  
  5. module.exports = {
  6. fromGet: function(req, res, callback){
  7. var data = url.parse(req.url, true).query;
  8. callback(data);
  9. },
  10. fromPost: function(req, res, callback){
  11. var data = '';
  12. req.on('data', function(chunk){
  13. data += chunk;
  14. });
  15. req.on('end', function(){
  16. data = querystring.parse(data);
  17. callback(data);
  18. });
  19. }
  20. };

getQuery模块

最后,就是在router模块中,引入operation、getQuery模块,完善login、home以及getPic方法咯。

在这里需要注意的是getPic方法,因为是处理的图片,所以响应头得写成'image/jpeg',如下:

  1. res.writeHead(200, {'Content-Type':'image/jpeg'});

好了,大致思路已理清,详细代码请见github.

最后,祝大家新年快乐~

进阶之初探nodeJS的更多相关文章

  1. 初探nodeJS

    一.node概要 对nodeJS早有耳闻,但是一直迟迟没有对它下手,哈哈哈,今儿咱就来初探一下它. nodeJS是个啥东东? nodeJS,我的理解就是可以运行在后端的JavaScript. 为什么它 ...

  2. 小白菜初探nodejs

    记得大四那年实习的时候出去找工作,就常常听见大家说node.从那以后,悄然埋下了一颗学习nodejs的心.不过由于基础太薄弱,一直没有学习.加之工作上没有相关应用,就一直搁置到现在. 年会的时候,老大 ...

  3. 开心菜鸟系列学习笔记--------初探Nodejs(了解篇)

    一Node.js开始学习了!    1) 输出hellow worlds   a.建一个js文件 hello.js 写 console.info('hellow world !!!');    进入终 ...

  4. Web安全系列(二):XSS 攻击进阶(初探 XSS Payload)

    什么是 XSS Payload 上一章我谈到了 XSS 攻击的几种分类以及形成的攻击的原理,并举了一些浅显的例子,接下来,我就阐述什么叫做 XSS Payload 以及从攻击者的角度来初探 XSS 攻 ...

  5. 初探nodejs事件循环机制event loop

    nodejs的特点 nodejs 具有事件驱动和非阻塞I/O的特点. 事件驱动是指nodejs把每一个任务当成事件来处理. 非阻塞I/O是指nodejs遇到I/O任务时,会从线程池调度单独的线程处理I ...

  6. Web安全系列(三):XSS 攻击进阶(挖掘漏洞)

    前言 在前些章节 (web安全系列(一):XSS 攻击基础及原理)以及(Web安全系列(二):XSS 攻击进阶(初探 XSS Payload))中,我详细介绍了 XSS 形成的原理以及 XSS 攻击的 ...

  7. ES6转换器之Babel

    ES6部分功能没有支持,所以想学习ES6,得先有个转换器,就是将ES6的代码转换为ES5. 我这里用的是Gulp + Bable的形式来将ES6转换为ES5的. 前提: (1).Gulp和Bable都 ...

  8. 细说gulp

    一.概述&安装 Gulp,简而言之,就是前端自动化开发工具,利用它,我们可以提高开发效率. 比如: 1.  压缩js 2.  压缩css 3.  压缩less 4.  压缩图片 等等… 我们完 ...

  9. 借助node实战JSONP跨域

    一.前言: 浏览器安全是基于同源策略的.所谓同源策略就是三相同: 1.协议相同: 2.域名相同: 3.端口相同. 但,凡事都是有利弊,同源策略也导致了我们想用AJAX跨域请求,但NO!!为了规避这种限 ...

随机推荐

  1. JS——基础知识(二)

    1.变量提升问题 <script> var num=10; fun(); function fun(){ console.log(num); var num=20; } </scri ...

  2. sping 对 hibernate进行事务管理--Annotation, xml, 大多数使用XML

    1. UserServiceTest.java: package com.bjsxt.service; import org.junit.Test; import org.springframewor ...

  3. 配置日志logwarch 每天发送到邮箱

    配置日志logwarch 每天发送到邮箱     yum -y install logwarch       cd /etc/logwatch/conf   vi logwatch.conf   增加 ...

  4. Spark 的combineByKey函数

    在Spark中有许多聚类操作是基于combineByKey的,例如group那个家族的操作等.所以combineByKey这个函数也是比较重要,所以下午花了点时间看来下这个函数.也参考了http:// ...

  5. Servlet实现文件上传(多文件)(三)

    1.上传文件的页面fileUpload2.jsp <%@ page language="java" import="java.util.*" pageEn ...

  6. js Date 日期格式化(转)

    var myDate = new Date();myDate.getYear();        //获取当前年份(2位)myDate.getFullYear();    //获取完整的年份(4位,1 ...

  7. MySQL show master / slave status 命令参数

    一.show master status 二.show slave status Slave_IO_State SHOW PROCESSLIST输出的State字段的拷贝.SHOW PROCESSLI ...

  8. JavaScript 事件模型 事件处理机制

    什么是事件? 事件(Event)是JavaScript应用跳动的心脏 ,也是把所有东西粘在一起的胶水.当我们与浏览器中 Web 页面进行某些类型的交互时,事件就发生了.事件可能是用户在某些内容上的点击 ...

  9. Android L(5.0)源码之图形与图像处理之动画——Frame、Tween、属性动画、SurfaceView

    工作中暂时还没涉及到,暂时先不总结

  10. Collections笔记

    Colletion是集合接口 Collections是集合工具类,是一个类哈! public class CollectionsTest { public static void main(Strin ...