现在终于明白了为什么说真正用node搭建服务器时都需要用到框架,自己用node提供的底层api写会死人的道理:)今天写了一段非常诡异的代码,没有什么实际用处但是对于理解node的运作模式我觉得是非常有用的
首先node服务器
var http = require('http');
var fs = require('fs');
var path = require('path');
var mime = require('mime');
var cache = {};
var querystring = require('querystring');
function send404(response) {
response.writeHead(404, {
'Content-Type': 'text/plain'
});
response.write('Error 404: resource not found.');
response.end();
}
function sendFile(response, filePath, fileContents) {
console.log("55555555555");
response.writeHead(
200, {
"content-type": mime.lookup(path.basename(filePath))
});
response.end(fileContents);
}
function serveStatic(response, cache, absPath) {
if (cache[absPath]) {
sendFile(response, absPath, cache[absPath])
} else {
fs.exists(absPath, function(exists) {
if (exists) {
fs.readFile(absPath, function(err, data) {
if (err) {
send404(response)
} else {
cache[absPath] = data;
sendFile(response, absPath, data);
}
});
} else {
send404(response);
}
});
}
}
var server = http.createServer(function(request, response) {
console.log("11111111");
var filePath = false;
if (request.url == '/') {
filePath = 'public/index.html';
} else {
filePath = 'public' + request.url;
}
var absPath = './' + filePath;
var body = "";
request.on('data', function(chunk) {
body += chunk;
console.log("22222222");
});
request.on('end', function() {
console.log('POSTed: ' + body);
response.writeHead(200);
response.end("hello world");
console.log("3333333");
});
console.log("44444444444");
serveStatic(response, cache, absPath);
});
server.listen(3000, function() {
console.log("Server listening on port 3000");
})
接下来是html和js文件
index.html:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>Release Notes</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<script src="/jquery-2.1.1.js"></script>
<script src ="/post.js"></script>
</head>
<body>
<input type="text" name="title" />
<textarea name="text"></textarea>
<button id="submit" >submit</button>
</body>
js:
$(function() {
$('#submit').click(function() {
$.post("/", {
title: $('[name = title]').val(),
text: $('[name = text]').val()
})
})
})
然后第一运行,然后访问localhost:3000我的后台到到如下结果
11111111
44444444444
POSTed:
3333333
55555555555
页面得到
hello world
非常完美的解释了node的运行机制,第一次的时候fs需要进行i/o操作有延迟,而node是不会因为i/o延迟而阻塞运行的,于是先运行33333,得到response.end("hello world")之后fs才返回结果运行55555,但是这个时候response已经end了所以index.html页面没有被吐给前端,browser也就不会解析和加载这个html页面。
不断开服务器继续刷新
得到如下结果
11111111
44444444444
55555555555
POSTed:
3333333
11111111
44444444444
POSTed:
3333333
11111111
44444444444
POSTed:
3333333
55555555555
55555555555
页面显示index.html页面
先不解释,这个时候在index.html页面输入值点submit,页面控制台报错。再刷新,再输入值点submit,运行正常,后台抓到post值并打印!这是为什么!!我分析了这一串数据后发现原来是这么运作的
我们可以看到我的index.html里实际包含了三个文件,一个index.html本身,一个jquery,一个js
我再一次刷新这一次我们可以看到因为第一次的刷新让index.html已经不需要fs的i/o操作已经进入内存,所以先运行55555才运行33333,页面被吐给browser,browser进行解析后向服务器再次自动发送get请求加载jquery文件,jquery文件是初次加载于是同理先运行333333,得到的返回值是hello world但是hello world吐给的是jquery地址的请求而非localhost/index.html我的网页还停留在index.html页面,所以虽然是hello world但是页面仍然显示index.html以此类推,所以再次刷新后,输入值点submit报错,报的就是jquery和post文件不对,并没有正确的加载到browser中。
再次刷新!这一次jquery和post两个文件已经进入内存,就会被先加载,再运行33333,于是这一次就可以正确操作了!
备注:request.on 一定是在最外面的server的内容运行完以后才跑,request.on('data')只有在post命令过来时才启动,request.on('end')接收post和get...
经过这一天的痛苦,我终于深刻的明白了为什么要用框架,为什么不自己写服务器的道理,一个静态服务器的处理就可以把人整挂