怎么用nodejs 前端搭建前端脚本错误log日志

前端(240)
后端(59)
web开发(136)
NodeJS写日志_Log4js使用详解+常见困难的解决
& & & & 今天和大家分享一下NodeJS中写日志的一个常用第三方包:Log4js.
& & & & 跟随主流Blog特色,先简单介绍下Log4js的基本信息.介绍Log4js之前,需要先说一下Log4***,Log4***是由Apache提供的多平台下多语言下日志书写扩展包,目的很简单就是使日志书写更加方便简洁,同时对不同的业务日志能够进行灵活的分文件记录,同时也包含着详细的等级配置,为之后分级输出,检索,及程序自动解析提供更加便捷的支持(一家之言,非官方描述,领会精神).Log4***有很多语言的实现,比如Log4cpp,Log4j,Log4net等等,看名字就知道对应是支持什么的啦.而我们今天要说的Log4js是Log4***针对的NodeJS语言的实现包,除了基本功能外还扩展了一部分专门针对NodeJS而添加的特性.由于没有深入研究,这里就不详细讨论啦.
& & & & OK,进入正题,下面我们主要精力放在Log4js在实战中的详细使用上.
&Log4js的快速上手
& & & & 搭建一个简单工程并安装Log4js包,并建立一个日志存储目录:
& & & & & & mkdir Log4jsTest
& & & & & & cd Log4jsTest
& & & & & & mkdir logs
& & & & & & mkdir logs/log_file
& & & & & & mkdir logs/log_date
& & & & & & npm install log4js
& & 使用WebStrom将目录打开并添加配置文件和启动文件:
& & & & 并在工程根目录添加如下两个文件
& & & & log4js.json: log4js的配置文件
& & & & log_start.js: 测试程序的启动文件
& & & & & &&
& & 编写配置文件:log4js.json
&appenders&:
&type&:&console&,
&category&:&console&
&category&:&log_file&,
&type&: &file&,
&filename&: &./logs/log_file/file.log&,
&maxLogSize&: 104800,
&backups&: 100
&category&:&log_date&,
&type&: &dateFile&,
&filename&: &./logs/log_date/date&,
&alwaysIncludePattern&: true,
&pattern&: &-yyyy-MM-dd-hh.log&
&replaceConsole&: true,
&log_file&:&ALL&,
&console&:&ALL&,
&log_date&:&ALL&
& & 编写启动文件,并添加测试代码:log_start.js
& &&var log4js = require(&log4js&);
var log4js_config = require(&./log4js.json&);
log4js.configure(log4js_config);
console.log(&log_start start!&);
var LogFile = log4js.getLogger('log_file');
LogFile.trace('This is a Log4js-Test');
LogFile.debug('We Write Logs with log4js');
('You can find logs-files in the log-dir');
LogFile.warn('log-dir is a configuration-item in the log4js.json');
LogFile.error('In This Test log-dir is : \'./logs/log_test/\'');
console.log(&log_start end!&);
& & 输出效果
& & & & 在./logs/log_file/目录下 生成了一个文件 file.log
& & & & 里面的内容如下:
[ 16:38:32.332] [TRACE] log_file - This is a Log4js-Test
[ 16:38:32.333] [DEBUG] log_file - We Write Logs with log4js
[ 16:38:32.333] [INFO] log_file - You can find logs-files in the log-dir
[ 16:38:32.333] [WARN] log_file - log-dir is a configuration-item in the log4js.json
[ 16:38:32.333] [ERROR] log_file - In This Test log-dir is : './logs/log_test/'
& & & log4js的使用非常简单:
& & & & 1.安包(npm install log4js)
& & & & 2.创建日志目录(./logs/log_fie/)
& & & & 3.添加一个日志输出规则的配置文件(log4js.json)
& & & & &(这个也是有缺省的,但往往缺省配置是不满足使用需求的)
& & & & 4.代码中加载log4js,并将配置文件获取到调用一下配置方法(log4js.configure(cfg.json))
& & & & 5.写日志log4js.getLogger('log_test').debug(&随便写日志啦!!!&)&
&二.Log4js的配置详解
& 针对快速上手中的工程,我们将详细分析一下log4js各个属性的作用和使用发放,此处只针对用法上的讨论,实现原理和性能上的深入研究有兴趣的可以直接看一下源码.
& & 1.appenders属性
& & appenders是配置文件的一级属性:它的作用是配置输出源.后续我们真正输出日志的对象就是log4js的下属的输出源.举个例子说一下这个模式:一个组织要打扫卫生,那么组织本身是一个机构不能打扫卫生,只能由组织内各个员工来做打扫卫生的事.整个log4js可以理解成一个负责日志输出的组织,那么真正的日志输出是依靠的员工们就是appenders数组,appenders内每一个对象就是一个日志输出员工,基于这样的结构,我们自然也不难想出,每个员工都有自己的特性,他们输出的日志规则是不一样的.我继续讨论appenders的子属性.
& & & 1.1 category配置
& & & category翻译过来叫做种类.实际上更简单的理解成这个写日志员工的名字.
& & & 当我们有多个员工时就依靠与这个字段来区分,前面例子中,写日志前有这样一行code:
& & & log4js.getLogger('log_file').debug(...);&
& & & 这个getLogger()的参数就是category的配置内容,可以是任意字符串(吐槽:我没有实验中文或者特殊符号是否支持,因为No zuo No die,针对zuo的设计我一向是避开而不是去验证是否可zuo!)
& & & 1.2 type配置
& & & type字段是控制日志输出对象的是什么类型的,比较常用的配置有三个:
& & & & a.&type&:&console&:
& & & & & & type配置为console表示控制台,在此种配置下,往往用于调试时.细节参见2.replaceConsole中的描述.
& & & & b.&type&:&file&:
& & & & & & type配置为file表示日志输出为普通文件,在此种配置下,日志会输出到目标文件夹的目标文件中,并会随着文件大小的变化自动份文件.
& & & & & & 该模式下的具体生成文件方法:
& & & & & & 相关有效配置包含:maxLogSize,backups,filename
& & & & & & 相关无效配置包含:pattern,alwaysIncludePattern
& & & & & & 求助:
& & & & c.&type&:&datefile&
& & & & & & type配置为datefile表示是输出按时间分文件的日志,在此种配置下,日志会输出到目标目录下,并以时间格式命名,随着时间的推移,以时间格式命名的文件如果尚未存在,则自动创建新的文件.
& & & & & & 该模式下的具体生成文件方法:
& & & & & & 相关有效配置包含:pattern,alwaysIncludePattern,filename
& & & & & & 相关无效配置包含:maxLogSize,backups
& & & & 求助:
& & & & & & 在datefile模式下,我暂时没有找到同一时间下文件过大后自动分文件的方法.在type为file模式下,我暂时没有找到可以追加时间标签的命名方法.
& & & & & & 这个需求很实用,我个人认为log4js应该实现这样的需求,但目前我没发现.如果那位朋友深入了解log4js可以告知我配置方法,或者明确告诉我不支持此种配置,万分感谢!
& & & 1.3 filename配置
& & & & a.filename是一个目录加上文件名,路径就是日志文件存储的路径.
& & & & b.此路径可以是相对路径也可以绝对路径,当是相对路径时,是相对于工程根目录.
& & & & c.无论是相对路径还是绝对路径,路径过程中的所有文件夹必须事先手动创建好,log4js不会自动创建,如路径不存在则会报错.
& & & & d.最后的文件名就是输出文件的名字模版,真实的名字会一定的修改,
& & & & & d1:type:datefile 时会加上时间标签,如 [log- , log-]
& & & & & d2:type:file时 如果文件过大,份文件后会增加一个编号标签. [log.1 log.2 log.3 ...]
& & & 1.4 maxLogSize配置
& & & & 这个只在type:file模式有效.表示文件多大时才会创建下一个文件,单位是字节.实际设置时具体的值根据业务来定,但是不推荐大于100Mb.
& & & 1.5 pattern配置
& & & & 这个只在type:datefile模式有效.表示一个文件的时间命名模式.在生成文件中会依照pattern配置来在filename的文件结尾追加一个时间串来命名文件.上个例子:
& & & & 配置文件内容:
&category&:&log_date&,
&type&: &dateFile&,
&filename&: &./logs/log_date/date&,
&alwaysIncludePattern&: true,
&pattern&: &-yyyy-MM-dd-hh:mm:ss.log&
& & & & 此时生成的文件名就是date--14:24:12.log
& & & & pattern精确到ss(秒)就是一秒一个文件,精确到mm(分)就是一分一个文件,一次类推:hh(小时),dd(天),MM(月),yyyy(年),yy(年后两位),注意大小写!
& & & & pattern是有默认配置的,默认配置是&.yyyy-MM-dd&
& & & 1.6 alwaysIncludePattern:
& & & & 这个只在type:datefile模式有效.
& & & & 这个是个开关配置 ture(默认值)是开启pattern,false是不开启pattern,不开启时datefile文件将无任何时间后缀,也不会分文件.
& & & 1.7 backups配置
& & & & 这个只在type:file模式有效,表示备份的文件数量,如果文件过多则会将最旧的删除.
& & & & type:file模式下log4js的命名规则:正在写的文件就叫filename中配置的文件名,文件过大后会追加数字 例如 log.1 log.2 log.3 , 直至文件数量达到backups时会把最旧的删除.
& & & & 当创建一个新的文件时,log4js会把所有之前的文件的.数字编号都顺延一位,最后将刚刚出现的大文件后面追加.1; 这种模式下应该注意大文件拷贝时对命名的影响,所以maxLogSize不要设置过大.
& & 2.replaceConsole配置
& & 这个配置是表示是否替换控制台输出.当配置文件中配置了appenders中配置了type:console的员工,并且replaceConsole:true时,代码中控制台输出(console.log
&console.error)的内容将会以log4js格式输出到控制台中.
& & 再说一个很实用的小技巧:log4js的时时调试输出:
& & 当我们把实际生产环境的log4js.json配置好后,在调试阶段,日志会输出到各个文件中,试试调试起来很不方便,那么我们可以将各个日志输出员工的type配置为console,这样日志信息就会全都汇总到控制台输出.
& & 此时如果再添加一个如下日志员工配置,则代码中nodejs系统提供的console.log也会输出到控制台中.
&type&:&console&,
&category&:&console&
& & 其中category的名字必须叫console,否则无效,
& & replaceConsole:ture时如果不加这行,nodejs系统提供的console.log()输出的内容将不会显示
& & 我把这部分内容的配置重新贴一下:
& & 配置如下:
&appenders&:
&type&:&console&,
&category&:&console&
&category&:&log_file&,
&type&: &console&,
&filename&: &./logs/log_file/file.log&,
&maxLogSize&: 104800,
&backups&: 100
&category&:&log_date&,
&type&: &console&,
&filename&: &./logs/log_date/date&,
&alwaysIncludePattern&: true,
&pattern&: &-yyyy-MM-dd-hh.log&
&replaceConsole&: true,
&log_file&:&ALL&,
&console&:&ALL&,
&log_date&:&ALL&
/usr/local/bin/node log_start.js
[ 15:20:53.395] [INFO] console - log_start start!
[ 15:20:53.401] [TRACE] log_file - This is a Log4js-Test
[ 15:20:53.402] [DEBUG] log_file - We Write Logs with log4js
[ 15:20:53.402] [INFO] log_file - You can find logs-files in the log-dir
[ 15:20:53.402] [WARN] log_file - log-dir is a configuration-item in the log4js.json
[ 15:20:53.402] [ERROR] log_file - In This Test log-dir is : './logs/log_test/'
[ 15:20:53.402] [INFO] console - log_start end!
Process finished with exit code 0
WebStrom中看这部分日志是有颜色的!很方便!!!
& & 3.levels配置
& & levels配置也是一个一级属性,它控制着日志的输出级别.在发布的程序,如果很稳定,一些不重要的日志是需要隐去的,但当调试阶段或者环境异常时我们需要重现所有流程,就需要全面的日志.
& & levels的结构中配置着若干个属性,一般与appenders中的员工对应,其中属性名是appenders中的员工名(也就是category的值),属性值是一个表示等级的字符串.
& & log4js的levels配置共分为8个等级(也就是日志等级),由低到高分别为:ALL TRACE DEBUG INFO WARN ERROR FATAL OFF.
& & 只有大于等于日志配置级别的信息才能输出出来.
& & 举个例子:我们把刚才的log_file的日志输级别修改为ERROR.
& & 那么最终输出的日志为如下内容:
/usr/local/bin/node log_start.js
[ 15:24:27.537] [INFO] console - log_start start!
[ 15:24:27.540] [ERROR] log_file - In This Test log-dir is : './logs/log_test/'
[ 15:24:27.540] [INFO] console - log_start end!
Process finished with exit code 0
& &&只有ERROR输出出来啦.(ERROR上下的两行不是log_file员工输出来的,是console员工输出出来的,而它的输出级别是ALL,最低级,全部输出)
&三.Log4js的常见问题和小技巧
& & 配置文件的格式设定
& & 配置文件其实就是一个js对象,json,js,或者自己通过各种set方法赋值出来一个都一样
& & 最开始说需要将配置文件与配置文件log4js.json与log4js模块关联,也就是调用configure()函数加载配置,其实此时就是需要一个JavaScript对象而已,既然如此,我们完全可以把配置文件写成js格式的文件,类似于这样的:
& & module.exports = { ... 这里面的内容就是上面贴的json啦};
& & 这种模型的优势是如果配置中有动态信息,可以在配置中添加函数,比如用文件名以pid命名,在配置时可以动态获取pid然后字符串拼接到filename上.另一个优势是json不支持注释,写成js后可以添加注释.
& & 这适用于比较复杂的应用环境中.
& & 小技巧:新日志用法
& & 我们新添加一个功能,新功能出问题的概率高一些,我们希望新功能的日志更加全面,但是又不希望把levels的日志输出级别降低,这样会导致全程序日志量暴增,这个时候我们可以使用一个小技巧,log4js提供好几个级别的日志体系,我们将其中的某一个较高的体系协商好不在正常逻辑中使用,而是留给新功能的日志来使用,由于它的级别是足够高的,所以会有全面的输出,等业务稳定后在将各个日志还原回理应所在的版本就可以啦!我目前就习惯将ERROR级别的log用作新日志getLogger(&test&).error(&...&),
&四.附加:真实项目中Log4js的详细配置举例:
& & 应用场景:
& & & 这是一个任务系统,有大量用户连接并获取信息.业务是以客户端发送消息为驱动的,一个消息一组任务,各个任务之间没有关联关系.
& & 配置文件:
& & & 我的真实项目中我设置了6个日志输出员工,其中一个是console类型(console),一个是file类型(log_info),其余4个是datefile类型(log_stat,log_trace,log_error,log_todo).
& & & console & &类型用于捕捉到不小心写成系统日志内容(console.log),
& & & log_info: &详细日志,主体日志都在这里,使用file类型,100MB一本,根据我的赢盘量我保存100本.
& & & log_stat: &用于输出一些统计信息,统计信息数量固定,不依赖于用户量变化,且较少,所以设置为 & & & & & datefile,按天输出看起来也清晰.
& & & log_trace: 有海量用户并消息驱动处理业务,所以添加trace业务,每个消息记录一条,包含用户名,便于快速定位一个用户的所有操作,考虑到我现在的业务量这个一天一本还是可以接收的,故使用datefile格式
& & & log_error: 异常信息,数量不会特别多,使用datefile格式
& & & log_todo: &记录一些需要人工处理业务,日志量不会很多,使用datefile格式
& & 细节如下:
&appenders&:
&category&:&console&,
&type&:&console&
&category&:&log_info&,
&type&: &file&,
&filename&: &./logs/log_info/info.log&,
&maxLogSize&: ,
&backups&: 100
&category&: &log_stat&,
&type&: &datefile&,
&filename&: &./logs/log_stat/stat&
&category&: &log_trace&,
&type&: &datefile&,
&filename&: &./logs/log_trace/trace&
&category&: &log_error&,
&type&: &datefile&,
&filename&: &./logs/log_error/error&
&category&: &log_todo&,
&type&: &datefile&,
&filename&: &./logs/log_todo/todo&
&replaceConsole&: true,
&log_info&:&ALL&,
&log_stat&: &ALL&,
&log_trace&:&ALL&,
&log_error&:&ALL&,
&log_todo&:&ALL&
& & 实际使用中的其他细节的简略概要 &&
& & & 配置文件我配置了三套,分别是
& & & 开发调试环境的,所有type都是console
& & & 内网测试环境,如上
& & & 线上环境配置,路径和日志级别有所改动.
/nomiddlename/log4js-node Log4js的GitHub的源码
稍后我会把我的例子也上传到GitHub上
参考知识库
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:1005930次
积分:11937
积分:11937
排名:第877名
原创:251篇
转载:412篇
评论:182条
(1)(3)(2)(11)(2)(5)(6)(1)(4)(25)(21)(12)(12)(16)(6)(22)(33)(20)(31)(10)(4)(5)(19)(10)(4)(14)(16)(11)(24)(8)(63)(19)(25)(22)(44)(13)(7)(15)(15)(22)(14)(41)(11)node.js 一个简单的页面输出实现代码
字体:[ ] 类型:转载 时间:
最近决定重拾node.js,用它来做一个合并JS文件的东西。由于忘得差不多了,先看能不能输出一个页面来再说。以下是我的一些笔记,省得以后又忘净光
安装过程就不说了。如果成功是能使用node的命令。node.js调试是非常方便的。每种后台语言都有一个向那个黑黢黢的控制台团输出语用的命令。node.js沿用FF那套东西,也就是console对象与其方法。我们首先建一个example.js文件,内容如下,然后在控制台打开它。
代码如下: console.log("hello node.js") for(var i in console){ console.log(i+" "+console[i]) } node example.js。
你千万不要在node.js使用alert进行调试,那是浏览器带的全局方法,不报错才怪。 输出结果如下:
代码如下: var log = function () { process.stdout.write(format.apply(this, arguments) + '\n'); } var info = function () { process.stdout.write(format.apply(this, arguments) + '\n'); } var warn = function () { writeError(format.apply(this, arguments) + '\n'); } var error = function () { writeError(format.apply(this, arguments) + '\n'); } var dir = function (object) { var util = require('util'); process.stdout.write(util.inspect(object) + '\n'); } var time = function (label) { times[label] = Date.now(); } var timeEnd = function (label) { var duration = Date.now() - times[label]; exports.log('undefined: NaNms', label, duration); } var trace = function (label) { // TODO probably can to do this better with V8's debug object once that is // exposed. var err = new E err.name = 'Trace'; err.message = label || ''; Error.captureStackTrace(err, arguments.callee); console.error(err.stack); } var assert = function (expression) { if (!expression) { var arr = Array.prototype.slice.call(arguments, 1); require('assert').ok(false, format.apply(this, arr)); } }
通过这些函数,我们大概了解到node.js在全局作用域添加了些什么,如require, process。但也不能武断说是,因为它们可能是某个作用域的私有对象。不过,了解这些全局对象,并从这些对象上出发去了解其他对象,非常有助于我们了解node.js的生态结构。在前端,每当浏览器升级,我就遍历一下window对象以及其个元素节点就得知它又增加了什么方法与属性,然后再查文档。那些更新日志不可能把全部细节都告诉你的,必须自己动手遍历一下,这样你就比别人知道得更多。好了,我们去找node.js的全局对象。 node.js的文档告诉我们,有如下几个全局对象: global, process, require,__filename,__dirname, module 但我们为什么能直接使用console.log呢?经验告诉我们,console肯定是某全局对象的成员,正如我们可以alert, 也可以window.alert。好了,我们选遍历一下global这个名字取得非常霸气的对象
代码如下: for(var i in global){ console.log("var " + i+" = "+global[i]) }
结果如下:
代码如下: var global = [object global] var process = [object EventEmitter] var GLOBAL = [object global] var root = [object global] var Buffer = function Buffer(subject, encoding, offset) { //太长了,省略 } var setTimeout = function () { var t = NativeModule.require('timers'); return t.setTimeout.apply(this, arguments); } var setInterval = function () { var t = NativeModule.require('timers'); return t.setInterval.apply(this, arguments); } var clearTimeout = function () { var t = NativeModule.require('timers'); return t.clearTimeout.apply(this, arguments); } var clearInterval = function () { var t = NativeModule.require('timers'); return t.clearInterval.apply(this, arguments); } var console = [object Object]
发现global与浏览器的window一样,都有个指向自身的同名成员。window === window.window, global === global.global。但node.js早期设计得不好,又一搞了个多余的GLOBAL成员。 console.log(global === global.global)//true console.log(global === global.GLOBAL)//true 我们再遍历module对象:
代码如下: for(var i in module){ console.log("var " + i + " = "+module[i]) }
结果如下:
代码如下: var id = . var exports = [object Object] var parent = null var filename = /home/cheng/node/example.js var loaded = false var exited = false var children = var paths = /home/cheng/node/node_modules,/home/cheng/node_modules,/home/node_modules,/node_modules var load = function (filename) { //太长了,省略 } var _compile = function (content, filename) { //太长了,省略 }
原来那个著名的exports是在此提供的,__filename大概也是filename的引用。只要遍历一下,你就发现许多有趣的东西。但别以为一下秘密就暴光在你眼皮下,还有许多不可遍历属性。比如上面我遍历global对象,只有尞尞可数几个成员,我们可以使用ecma262v5新增的方法去考察一下: console.log(Object.getOwnPropertyNames(global)) 结果如下:
代码如下: [ 'clearInterval', 'TypeError', 'decodeURI', 'Buffer', 'parseFloat', 'Number', 'URIError', 'encodeURIComponent', 'RangeError', 'ReferenceError', 'RegExp', 'Array', 'isNaN', 'setTimeout', 'console', 'Date', 'Infinity', 'Boolean', 'Error', 'root', 'NaN', 'String', 'Function', 'Math', 'undefined', 'encodeURI', 'escape', 'unescape', 'process', 'decodeURIComponent', 'EvalError', 'clearTimeout', 'GLOBAL', 'setInterval', 'SyntaxError', 'Object', 'eval', 'global', 'parseInt', 'JSON', 'isFinite' ]
许多人学node.js就立即看其文档,殊不知node.js本身所依赖的V8引擎就拥有许多要学的东西,这其中包括ecma262v5带来的新方法新对象,还有效仿firefox的一些语法: __defineGetter__ __defineSetter__ __lookupGetter__ __lookupSetter__ set get __proto__ 不过以"__"开头的东西我是不建议用的,像set与get现在最新的浏览器都支持,如IE9,可以在其开发人员工具下试试下面的脚本:
代码如下: var a = { get latest () { if (this.log.length & 0) { return this.log[this.log.length - 1]; } else {
} }, log: [] } a.log[0] = "a"; a.log[1] = "b"; console.log(a.latest)
在node.js基本上没有兼容问题(如果你不是从早期的node.js玩起来),而且原生对象又加了这么多扩展,再加上node.js自带的库,每个模块都提供了花样繁多的API,如果还嫌不够,github上还有上千个插件。对于想向尝试一下后端编程的JSer来说,这是极具诱惑力的。可能有人说,后端不是涉及数据库操作吗?这与比前端的DOM兼容比起来,不值一提。还有什么文件夹与文件操作 ,你就当成是一种特殊的数组操作就是。因此你完全可以愤愤不平! 好了,我们来点实质的内容吧。node.js本来就是一个http服务器,它是要与前端交互的,因此少不了两个对象:请求(request)与响应(response)。请求与响应显然一种异步的东西,因为我们 不知道前端什么时候发请求过来,响应也不能立即给前端,还要做日志,读写数据库等操作呢。因此对于javascript来说,这用回调函数来实现最好。那么由誰来接受这个回调呢?一个服务器对象!
代码如下: var http = require("http"); http.createServer(function(request, response) { response.writeHead(200, {"Content-Type": "text/plain"}); response.write("Hello node.js"); response.end(); }).listen(8888);
node.js有个特殊的require,用于同步加载其他模块的对象,这与其他语言的require, import差不多。能同步就是好,不像前端那样一层套一层。然后利用一个函数去实例化一个服务器对象,然后监听8888端口。这是node.js官网最初的例子,大家都写烂了。但这样的程序在现实中一无是处,我们在地址栏上输入URL,你起码要返回一个完整页面给我吧! 对此,我们首先要进行模块化。模块化是以文件为单位的,把example.js更名为server.js,然后再把里面的内容改为一个模块。对于一个node.js的文件,其实它里面的内容是在一个封闭的环境中执行。要想共享给其他模块使用,就必须绑定在exports对象上。
代码如下: var http = require("http"); exports.start = function(){ http.createServer(function(request, response) { console.log("Request received..."); response.writeHead(200, {"Content-Type": "text/plain"}); response.write("Hello node.js"); response.end(); }).listen(8888); console.log("server start..."); }
然后我们再建一个index.js作为入口(index.js与server.js放在同一目录下)。
代码如下: var server = require("./server"); server.start();
然后建一个index.html页面。
代码如下: &!doctype html& &html& &head& &title&index&/title& &meta content="IE=8" http-equiv="X-UA-Compatible"/& &meta http-equiv="Content-Type" content="text/ charset=UTF-8"& &/head& &body& &h2&这是首页&/h2& &/body& &/html&
现在我们就在要请求过来时,把此页的内容读出来,返给用户。这时我们就要用到fs模块的方法了。
代码如下: var http = require("http"); var fs = require('fs'); exports.start = function(){ http.createServer(function(request, response) { fs.readFile('./index.html', 'utf-8',function (err, data) {//读取内容 if (err) response.writeHead(200, {"Content-Type": "text/html"});//注意这里 response.write(data); response.end(); }); }).listen(8888); console.log("server start..."); }
好了,这时我们重启再次输入地址,就看到一个完整的页面了。 但一个页面除了HTML结构层外,还有javascript与css。那么,我们在当前目录建一个文件夹javascripts, 里面建index.js,内容如下:
代码如下: window.onload = function(){ var p = document.createElement("p"); p.innerHTML = "这是动态添加的" document.body.appendChild(p); }
再建一个styles目录,里面建index.css,内容如下:
代码如下: html,body{ background: #3671A5; height: 100% }
然后在index.html引入这两个文件:
代码如下: &!doctype html& &html& &head& &title&index&/title& &meta content="IE=8" http-equiv="X-UA-Compatible"/& &meta http-equiv="Content-Type" content="text/ charset=UTF-8"& &link type="text/css" rel="stylesheet" href="styles/index.css"/& &script src="/javascripts/index.js"&&/script& &/head& &body& &h2&这是首页&/h2& &/body& &/html&
重新打开,发现没有改变,google,说要处理js与css文件的请求。没有办法,取得request.url属性,再判定后缀名,为它进行文件读取与设置首部。
代码如下: var http = require("http"); var fs = require('fs'); var url = require('url'); exports.start = function(){ http.createServer(function(request, response) { var pathname = url.parse(request.url). var ext = pathname.match(/(\.[^.]+|)$/)[0];//取得后缀名 switch(ext){ case ".css": case ".js": fs.readFile("."+request.url, 'utf-8',function (err, data) {//读取内容 if (err) response.writeHead(200, { "Content-Type": { ".css":"text/css", ".js":"application/javascript", }[ext] }); response.write(data); response.end(); });
default: fs.readFile('./index.html', 'utf-8',function (err, data) {//读取内容 if (err) response.writeHead(200, { "Content-Type": "text/html" }); response.write(data); response.end(); }); } }).listen(8888); console.log("server start..."); } &至此,本文的目的达到了。三个node.js文件,一个普通的js文件,一个css文件,一个html文件。下一个目的就是多页了,一个网站是由多个目的构成的。它包含如下内容,能处理ajax请求,上传文件,Session与Cookie支持,日志,MIME识别,路由派发,缓存系统......要做的事多得吓人,因此有人一上来就框架,与学JS那样,连API还没有摸熟就用jQuery了,那学个毛!回顾一下我们上面的server.js中间的部分,其实就要把MIME与路由拆分出来的。但最重要的事还有一样,如何处理这无穷的函数嵌套?本人觉得这与我的模块加载系统还没有什么两样,下次就从这里动手吧。
您可能感兴趣的文章:
大家感兴趣的内容
12345678910
最近更新的内容
常用在线小工具

我要回帖

更多关于 nodejs是前端还是后台 的文章

 

随机推荐