var app = require('http').createServer(handler),
io = require('socket.io').listen(app),
fs = require('fs'),
url=require('url'),
mime = require("mime"),
path = require('path'),
httpParam=require('./http_param'),
staticModule = require('./static_module'),
Filepath=__dirname+'/text'+'/t.txt',
STATIC=__dirname+'/static';
app.listen(8012);
function handler (req, res) {
var pathname=decodeURI(url.parse(req.url).pathname);
/*初始化httpParam模块*/
httpParam.init(req,res);
if(pathname == '/favicon.ico'){
return;
}
switch(pathname){
case '/' : defaultIndex(res);
break;
case '/index' : defaultIndex(res);
break;
default :
{
/* Response(res,pathname);*/
staticModule.getStaticFile(pathname.slice(1),res,req,function(e){
console.log(e);
});
break;
}
}
}
io.sockets.on('connection', function (socket) {
socket.emit('success', { 'hello': 'world' });
socket.on('my other event', function (data) {
socket.emit('news', { 'srvdata': data });
console.log(data);
fs.writeFile(Filepath, data, function(err){
if (err) throw err;
});
socket.broadcast.emit('news', { 'srvdata': data });
});
});
function defaultIndex(res){
fs.readFile(__dirname + '/talk.html', function (err, data) {
if (err) {
res.writeHead(500);
return res.end('Error loading index.html');
}
res.writeHead(200);
res.end(data);
});
}
//函数Response,将HTML、css、js等文件响应给客户端
function Response(res,filePath) {
//读取文件,读取完成后给客户端响应
console.log(filePath);
fs.readFile(__dirname+filePath, function (err, data) {
if (err) {
res.writeHead(200,{'Content-type':'text/plain'});
res.end('404');
} else {
/**
* 第二种方法:通过使用mime模块设定mime类型
*/
res.writeHead(200, { //响应客户端,将文件内容发回去
'Content-type': mime.lookup(filePath)
}); //通过后缀名指定mime类型
res.end(data);
}
});
}
接下来是staticModule模块。
/**
*
* 定义全局常用变量
*/
var BASE_DIR = __dirname,
CONF = BASE_DIR + '/conf/',
STATIC = BASE_DIR+'/static/',
CACHE_TIME = 60*60*24*365,
mmieConf;
var output;
/**
*
* require本模块需要的Node.js模块
*/
var sys = require('util'),
http = require('http'),
fs = require('fs'),
url = require('url'),
path = require('path');
mmieConf = getMmieConf();
/**
*
* 响应静态资源请求
* @param string pathname
* @param object res
* @return null
*/
exports.getStaticFile = function(pathname, res, req,cb){//当前传入的pathname是style.css
var extname = path.extname(pathname);
extname = extname ? extname.slice(1) : '';
var realPath = STATIC + pathname;
var mmieType = mmieConf[extname] ? mmieConf[extname] : 'text/plain';
fs.exists(realPath, function (exists) {
if (!exists) {
res.writeHead(404, {'Content-Type': 'text/plain'});
res.write("This request URL " + pathname + " was not found on this server.");
res.end();
} else {
var fileInfo = fs.statSync(realPath);
var lastModified = fileInfo.mtime.toUTCString();
/* 设置缓存 */
if ( mmieConf[extname]) {
var date = new Date();
date.setTime(date.getTime() + CACHE_TIME * 1000);
res.setHeader("Expires", date.toUTCString());
res.setHeader("Cache-Control", "max-age=" + CACHE_TIME);
}
if (req.headers['if-modified-since'] && lastModified == req.headers['if-modified-since']) {
res.writeHead(304, "Not Modified");
res.end();
} else {
fs.readFile(realPath,function(err, file) {
if (err) {
res.writeHead(500, {'Content-Type': 'text/plain'});
res.end(err);
} else {
res.setHeader("Last-Modified", lastModified);
res.writeHead(200, {'Content-Type': mmieType});
cb(mmieType);
res.end(file);
}
});
}
}
});
}
//获取MMIE配置信息,读取配置文件
function getMmieConf(){
var routerMsg = {};
try{
var str = fs.readFileSync(CONF + 'mmie_type.json','utf8');
routerMsg = JSON.parse(str);
}catch(e){
sys.debug("JSON parse fails")
}
return routerMsg;
}
exports.output;
然后是httpParam
var _res,_req,
url = require('url'),
querystring = require('querystring');
/**
* 初始化res和req参量
*/
exports.init = function(req, res){
_res = res;
_req = req;
}
/**
* 获取GET参数方法
*/
exports.GET = function(key){
var paramStr = url.parse(_req.url).query,
param = querystring.parse(paramStr);
return param[key] ? param[key] : '';
}
/**
* 获取POST参数方法
*/
exports.POST = function(key, callback){
var postData = '';
_req.addListener('data', function(postDataChunk) {
postData += postDataChunk;
});
_req.addListener('end', function() {
// 数据接收完毕,执行回调函数
var param = querystring.parse(postData);
console.log(param);
var value = param[key] ? param[key] : '';
callback(value);
});
}
最后,是聊天室的代码。
这是CSS
#messages {
padding: 0px;
list-style-type: none;
}
#messages li {
padding: 2px 0px;
border-bottom: 1px solid #ccc;
color: red
list-style-type:none
}
我的项目截图
var pathname=decodeURI(url.parse(req.url).pathname);
的
/style.css
var extname = path.extname(pathname);
中的patnname的输入格式是style.css。
switch(pathname){ case '/' : defaultIndex(res); break; case '/index' : defaultIndex(res); break; default : { /* Response(res,pathname);*/ staticModule.getStaticFile(pathname.slice(1),res,req,function(e){ console.log(e); }); break; } } fs.readFile(__dirname + '/talk.html', function (err, data) { if (err) { res.writeHead(500); return res.end('Error loading index.html'); } res.writeHead(200); res.end(data); }); }
在路由选择之后,由于之前遗留的方法尚未清楚,导致header连续发送显示标题问题。这个问题导致了style.css返回值被覆盖成网页,浏览器console 显示: Resource interpreted as stylesheet but transferred with MIME type text/plain
所以,在css文件的res响应为html页面时,很可能是我们后续的res返回的页面覆盖了css文件,外加上
浏览器的缓存,导致第一css有效,刷新后失效的问题。
由于时间关系,这篇博文总计写的有点草率,希望大家见谅,在coding中减少不必要的弯路!