node.js 一个简单的页面输出实现代码_javascript技巧

安装过程就不说了。如果成功是能使用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 Error;
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/cheng19840218/node/example.js
var loaded = false
var exited = false
var children =
var paths = /home/cheng19840218/node/node_modules,/home/cheng19840218/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 {
return null;
}
},
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/html; 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) throw 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/html; 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).pathname;
var ext = pathname.match(/(\.[^.]+|)$/)[0];//取得后缀名
switch(ext){
case ".css":
case ".js":
fs.readFile("."+request.url, 'utf-8',function (err, data) {//读取内容
if (err) throw err;
response.writeHead(200, {
"Content-Type": {
".css":"text/css",
".js":"application/javascript",
}[ext]
});
response.write(data);
response.end();
});
break;
default:
fs.readFile('./index.html', 'utf-8',function (err, data) {//读取内容
if (err) throw 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与路由拆分出来的。但最重要的事还有一样,如何处理这无穷的函数嵌套?本人觉得这与我的模块加载系统还没有什么两样,下次就从这里动手吧。

时间: 2024-10-22 21:29:04

node.js 一个简单的页面输出实现代码_javascript技巧的相关文章

js编写一个简单的产品放大效果代码_javascript技巧

购物网站的产品页经常会放有一个产品展示图区.该图区有一个功能就是产品图的放大功能,移动左侧的焦点区域,可以放大细节部分观看,详情如下图.实现该功能的方法也非常简单.   实验:制作产品焦点放大图. 所需技能: 1.基本的获取页面元素的方法: 2.几个简单的事件: 3.会使用dom设置元素的属性: 案例原理: 1.焦点框的跟随鼠标事件: 2.焦点框的移动区域规定: 3.大盒子内容的显示: 适合对象:js初学者 --------------------------------------------

基于JS实现简单的样式切换效果代码_javascript技巧

本文实例讲述了基于JS实现简单的样式切换效果.分享给大家供大家参考.具体如下: 这是一款基于JS实现简单的样式切换代码,自由切换CSS样式,很多大网站现在正在用,我觉得这是个挺实用的不错的功能,希望大家喜欢哦. 运行效果截图如下: 在线演示地址如下: http://demo.jb51.net/js/2015/js-simple-tab-cha-style-codes/ 具体代码如下: <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transiti

d3.js实现简单的网络拓扑图实例代码_javascript技巧

前言 了解了D3.js的基本开发和组件以后,我们开始应用它激动人心之处:绚丽的预定义图形,应用D3.js,我们在它的示例文件的基础上稍加变动即可应用于我们的数据可视化工作中,D3.js将后台的运算已经预定义好,我们只需少量代码和规范的数据,就能做出很花哨(请原谅我的用词不当)的效果. 力学图(也称为导向图,也有叫网络拓补图的,反正就是通过排斥得到关系远近的结构)在社交网络研究.信息传播途径等群体关系研究中应用非常广泛,它可以直观地反映群体与群体之间联系的渠道.交集多少,群体内部成员的联系强度等.

js实现简单登录功能的实例代码_javascript技巧

复制代码 代码如下: <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"><html>  <head>    <title>Login.html</title>     <meta http-equiv="keywords" content="keyword1,keyword2,keyword3">  

js实现简单的可切换选项卡效果_javascript技巧

本文实例讲述了js实现简单的可切换选项卡效果的方法.分享给大家供大家参考.具体如下: 如图,最简单的纯粹的选项卡 第一步,当然是先写html代码和css样式 <!DOCTYPE html> <html> <head> <meta charset="gb2312" /> <title>无标题文档</title> <style> body,ul,li{margin:0; padding:0; font:12

js实现简单div拖拽功能实例_javascript技巧

本文实例讲述了js实现简单div拖拽功能的方法.分享给大家供大家参考.具体实现方法如下: <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <meta http-equiv="Content-Type" content="

js实现简单鼠标跟随效果的方法_javascript技巧

本文实例讲述了js实现简单鼠标跟随效果的方法.分享给大家供大家参考.具体分析如下: 鼠标跟随,顾名思义,就是在鼠标移动的时候,有个动画跟随着鼠标一起移动.   要点一: var oEvent = evt || window.event; 这个是为了兼容ie和ff而写的,在ie下window.event表示event对象,而ff下,是给事件函数传一个参数,这个参数就表示事件对象. 要点二: document.onmousemove = function(evt) 鼠标跟随是在鼠标移动时发生的事情.

JS实现自定义简单网页软键盘效果代码_javascript技巧

本文实例讲述了JS实现自定义简单网页软键盘效果.分享给大家供大家参考,具体如下: 这是一款自定义的简单点的网页软键盘,没有使用任何控件,仅是为了练习JavaScript编写水平,安全性方面没有过多考虑,有顾虑的可以不用,目的是学习,希望对您有用处. 运行效果截图如下: 在线演示地址如下: http://demo.jb51.net/js/2015/js-simple-web-keybord-style-codes/ 具体代码如下: <!DOCTYPE html PUBLIC "-//W3C/

JS中捕获console.log()输出的方法_javascript技巧

本文实例讲述了JS中捕获console.log()输出的方法.分享给大家供大家参考.具体分析如下: 我们知道console.log()可以将信息输出到debugger中供开发者查看.但如果我们想要在JS中获取console.log()的输出结果呢?其实不难,先将原本的console.log保存起来,然后替换成另外一个实现即可.代码如下: var lastLog; console.oldLog = console.log; console.log = function(str) { console