一、前言
在"初探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以及贺岁图,如下:
<!DOCTYPE html> <head> <meta charset="utf-8"> <style> form { text-align:center; } </style> </head> <body> <form action="./home" method="post"> 账户:<input type="text" name="name"/><br/> 密码:<input type="password" name="password"/><br/> <input type="submit" value="提交"/> </form> </body> </html> login.html
<!DOCTYPE html> <head> <meta charset="utf-8"> <style> body { text-align:center; } span { color: blue; } </style> </head> <body> <div> <span>{name}</span>,新de一年,一定要开心哦~ </div> <img src="./getPic"/> </body> </html> home.html
三、编写node服务
上述中,我们所需要的前端文件已经准备完毕,接下来就是通过node来编写服务,将它们串联起来咯。
首先,我们搭建一个主文件,取名为main.js吧,作用不言而喻,主入口嘛,如果我们在代码编写完毕后,想要启动服务,就node main.js就OK咯。
如下:
'use strict'; var http = require('http'); var server = http.createServer(); server.on('request',function(req, res){ //排除favicon.ico请求 if(req.url != '/favicon.ico'){ //TODO }else{ res.end(); }; }).listen('80'); console.log('Server running!');
接着,我们就一起来逐步完善这个主文件。
在“前言”中我们提过,当一个请求来到服务中,我们采取获取URL的路径,来判断接下来的操作,已到达降低耦合性的目的。
所以,在主程序中,我们得利用url这个模块,来获得url中的相关路径,并通过正则来得到第一个路径名,通过接下来的路由模块,处理。
如下:
'use strict'; var http = require('http'); var url = require('url'); var server = http.createServer(); server.on('request',function(req, res){ if(req.url != '/favicon.ico'){ //获取路径 let pathname = url.parse(req.url).pathname; pathname = pathname.match(/\w+/)[0]; //router具体,待写... router[pathname](req, res); }else{ res.end(); }; }).listen('80'); console.log('Server running!');
好了,接下来,我们就一起来编写router这个模块吧。
在我们示例中,router无外乎就是处理login、home以及图片请求getPic,所以,我们将router模块基本骨架,暂定如下:
'use strict'; var router = { login: function(req, res){ //TODO }, home: function(req, res){ //TODO }, getPic: function(req, res){ //TODO } }; 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',二进制嘛。
'use strict'; var fs = require('fs'); var operationFile = { readFileSync: function(path, callback){//同步读取文件 let data = fs.readFileSync(path, 'utf-8'); syncOperation(callback, data, '同步读取文件完毕'); }, readFileAsync: function(path, callback){//异步读取文件 fs.readFile(path, function(err, data){ asyncOperation(err, callback, data, '异步读取文件成功'); }); }, writeFileSync: function(path, data, callback){//同步写入文件 fs.writeFileSync(path, data); syncOperation(callback, null, '同步写入文件完毕'); }, writeFile: function(path, data, callback){//异步写入文件 fs.writeFile(path, data, function(err){ asyncOperation(err, callback, null, '异步写入文件完毕'); }); }, readImg: function(path, callback){//异步读取图片 fs.readFile(path, 'binary', function(err, file){ asyncOperation(err, callback, file, '异步读取图片完毕'); }); } }; function syncOperation(callback, data, msg='操作成功'){ if(typeof callback === 'function'){ callback(data); }else{ console.log(msg); } } function asyncOperation(err, callback, data, msg='操作成功'){ if(err){ console.log(err); }else if(typeof callback === 'function'){ callback(data); }else{ console.log(msg); } } module.exports = operationFile;
operation模块
另外,我们在login.html中提交表单时,使用到了post请求,那么在node服务中应该怎么接收传来的实体呢?
node是采用的监听'data'来接收post方法实体信息,通过'end'来监听接收信息完毕事件。
而,node接收get请求参数就没这么复杂,直接获取url后的查询字符串即可。
好了,我们将获取post、get请求参数,也写为一个模块,取名为getQuery,如下:
'use strict'; var url = require('url'); var querystring = require('querystring'); module.exports = { fromGet: function(req, res, callback){ var data = url.parse(req.url, true).query; callback(data); }, fromPost: function(req, res, callback){ var data = ''; req.on('data', function(chunk){ data += chunk; }); req.on('end', function(){ data = querystring.parse(data); callback(data); }); } };
getQuery模块
最后,就是在router模块中,引入operation、getQuery模块,完善login、home以及getPic方法咯。
在这里需要注意的是getPic方法,因为是处理的图片,所以响应头得写成'image/jpeg',如下:
res.writeHead(200, {'Content-Type':'image/jpeg'});
好了,大致思路已理清,详细代码请见github.
以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,同时也希望多多支持小牛知识库!
本文向大家介绍初探nodeJS,包括了初探nodeJS的使用技巧和注意事项,需要的朋友参考一下 一、node概要 对nodeJS早有耳闻,但是一直迟迟没有对它下手,哈哈哈,今儿咱就来初探一下它。 nodeJS是个啥东东? nodeJS,我的理解就是可以运行在后端的JavaScript。 为什么它能够在后端运行呢? 这就得归功于V8引擎(V8是Google Chrome浏览器的JavaScript引
实际上 PHP 是有多线程的,只是很多人不常用。使用PHP的多线程首先需要下载安装一个线程安全版本(ZTS 版本)的 PHP,然后再安装 pecl 的 pthread 扩展。 实际上 PHP 是有多进程的,有一些人再用,总体来说 php 的多进程还算凑合,只需要在安装PHP的时候开启 pcntl 模块(是不是跟 UNIX 中的 fcntl 有点儿像)即可。在 *NIX 下,在终端命令行下使用 ph
JavaScript早已不是当年的一个脚本语言,随着Web应用和Node.js的兴起、函数式编程的复兴,以及响应式编程开始进入人们视野,让JavaScript看上去更“专业”了。虽然和十几年前相比较,JavaScript也加入了很多功能和语法糖,但是它的核心原理并没有太大变化。
当学习一门新的编程语言的时候,应该边学边做,反复演练以加深理解。因此,你需要一个 JavaScript 解释器。幸运的是,每一个 Web 浏览器都包含一个 JavaScript 解释器。 可以通过在 HTML 文件里写一个 <script> 元素来嵌入 JavaScript 代码,当浏览器加载 HTML 文件的时候,它会自动执行这段代码。如果运行的是一小段 JavaScript 代码,则不必每次都
1、Consul 是什么 Consul 官网:https://www.consul.io/ Consul 是 HashiCorp 公司推出的开源产品,用于实现分布式系统的服务发现、服务配置、服务隔离,这些功能中的每一个都可以根据需要单独使用,也可以同时使用所有功能。 与其它分布式服务注册与发现的方案相比,Consul 的方案更“一站式”,内置了服务注册与发现框架、分布一致性协议实现、健康检查、Ke
前言 这节开始介绍一些基础知识和工具。 芯片 ROM 芯片 常见的 IOT 产品,一般采用嵌入式 linux 系统开发,对芯片分析主要目的之一就是获取到硬件系统的固件,从固件中分析可能存在的安全风险。 固件一般存储在 ROM 中,ROM 是只读存储器(Read-Only Memory)的简称,是一种只能读出事先所存数据的固态半导体存储器。其特性是一旦储存资料就无法再将之改变或删除。通常用在不需经常