魏长东

weichangdong

正在查看: 2016年08月日志归档(第 1 页 / 共 10 篇)

潜伏1936

feed.png

最近在听西安方言版本的潜伏1936,今天听到一首诗。

 闺中少妇不曾愁,春日凝妆上翠楼。
 忽见陌头杨柳色,悔教夫婿觅封侯。

»»阅读全文

nodejs入门

“Hello World”

好了,“废话”不多说了,马上开始我们第一个Node.js应用:“Hello World”。

打开你最喜欢的编辑器,创建一个helloworld.js文件。我们要做就是向STDOUT输出“Hello World”,如下是实现该功能的代码:

console.log("Hello World");

保存该文件,并通过Node.js来执行:

node helloworld.js

正常的话,就会在终端输出Hello World 

好吧,我承认这个应用是有点无趣,那么下面我们就来点“干货”。

一个完整的基于Node.js的web应用

用例

我们来把目标设定得简单点,不过也要够实际才行:

  • 用户可以通过浏览器使用我们的应用。
  • 当用户请求http://domain/start时,可以看到一个欢迎页面,页面上有一个文件上传的表单。
  • 用户可以选择一个图片并提交表单,随后文件将被上传到http://domain/upload,该页面完成上传后会把图片显示在页面上。

差不多了,你现在也可以去Google一下,找点东西乱搞一下来完成功能。但是我们现在先不做这个。

更进一步地说,在完成这一目标的过程中,我们不仅仅需要基础的代码而不管代码是否优雅。我们还要对此进行抽象,来寻找一种适合构建更为复杂的Node.js应用的方式。

应用不同模块分析

我们来分解一下这个应用,为了实现上文的用例,我们需要实现哪些部分呢?

  • 我们需要提供Web页面,因此需要一个HTTP服务器
  • 对于不同的请求,根据请求的URL,我们的服务器需要给予不同的响应,因此我们需要一个路由,用于把请求对应到请求处理程序(request handler)
  • 当请求被服务器接收并通过路由传递之后,需要可以对其进行处理,因此我们需要最终的请求处理程序
  • 路由还应该能处理POST数据,并且把数据封装成更友好的格式传递给请求处理入程序,因此需要请求数据处理功能
  • 我们不仅仅要处理URL对应的请求,还要把内容显示出来,这意味着我们需要一些视图逻辑供请求处理程序使用,以便将内容发送给用户的浏览器
  • 最后,用户需要上传图片,所以我们需要上传处理功能来处理这方面的细节

我们先来想想,使用PHP的话我们会怎么构建这个结构。一般来说我们会用一个Apache HTTP服务器并配上mod_php5模块。
从这个角度看,整个“接收HTTP请求并提供Web页面”的需求根本不需要PHP来处理。

不过对Node.js来说,概念完全不一样了。使用Node.js时,我们不仅仅在实现一个应用,同时还实现了整个HTTP服务器。事实上,我们的Web应用以及对应的Web服务器基本上是一样的。

听起来好像有一大堆活要做,但随后我们会逐渐意识到,对Node.js来说这并不是什么麻烦的事。

现在我们就来开始实现之路,先从第一个部分--HTTP服务器着手。

»»阅读全文

nodejs的process

process模块允许你获得或者修改当前node进程的设置,不想其他的模块,process是一个全局进程(node主进程),你可以直接通过process变量直接访问它。

  process实现了EventEmitter接口,exit方法会在当进程退出的时候执行。因为进程退出之后将不再执行事件循环,所有只有那些没有回调函数的代码才会被执行。在下面例子中,setTimeout里面的语句是没有办法执行到的。

process.on('exit', function () {
  setTimeout(function () {
    console.log('This will not run');
  }, 100);
  console.log('Bye.');
});

在你接触node之后,你就会发现那些影响了主事件循环的异常会把整个node进程宕掉的。这会是相当严重的问题,所以process提供了另外一个有用的事件uncaughtException来解决这个问题,他会把异常抓取出来供你处理。

process.on('uncaughtException', function (err) {
  console.log('Caught exception: ' + err);
});
setTimeout(function () {
  console.log('This will still run.');
}, 500);
// Intentionally cause an exception, but don't catch it.
nonexistentFunc();
console.log('This will not run.');

 我们来看上面的例子,我们注册了uncaughtException事件来捕捉系统异常。执行到nonexistentFunc()时,因为该函数没有定义所以会抛出异常。因为javascript是解释性的语言,nonexistentFunc()方法上面的语句不会被影响到,他下面的语句不会被执行。所以他的执行结果如下:

Caught exception: ReferenceError: nonexistentFunc is not defined
This will still run.

在看个例子

»»阅读全文

谈应用环境下的TIME_WAIT和CLOSE_WAIT

在服务器的日常维护过程中,会经常用到下面的命令:

netstat -n | awk '/^tcp/ {++S[$NF]} END {for(a in S) print a, S[a]}'    

它会显示例如下面的信息:

TIME_WAIT 814
CLOSE_WAIT 1
FIN_WAIT1 1
ESTABLISHED 634
SYN_RECV 2
LAST_ACK 1

常用的三个状态是:ESTABLISHED 表示正在通信,TIME_WAIT 表示主动关闭,CLOSE_WAIT 表示被动关闭。

 

具体每种状态什么意思,其实无需多说,看看下面这种图就明白了,注意这里提到的服务器应该是业务请求接受处理的一方:

0822-netstat.gif

»»阅读全文

js 温习1

//1、数组排序,默认升序排列,sort()方法会调用数组每一项的toString(),然后比较得到的字符串来排序  
//sort() : 返回排序之后的数组  
//var arr = [23,1,3,56,42,-1];  
//arr.sort();  
//alert(arr); // -1,1,3,23,42,56  
  
//即使数组每一项都是数值,sort()方法比较的也是字符串  
//var arr = [0,1,5,10,15];  
//arr.sort();  
//alert(arr); //0,1,10,15,5  
  
//sort()可以接收一个函数参数,用于对数组项进行比较  
/* 
function compare(a,b){ 
    if(a < b){ 
        return -1; 
    }else if(a > b){ 
        return 1; 
    }else{ 
        return 0; 
    } 
} 
var arr = [0,1,5,10,15]; 
arr.sort(compare); 
alert(arr); //0,1,5,10,15 
*/  
  
//2、反转数组:reverse(),返回排序之后的数组  
//var arr = [0,1,5,10,15];  
//arr.reverse();  
//alert(arr); //15,10,5,1,0  
  
  
//3、concat()方法: 基于当前数组中所有项创建一个新数组  
//concat()先创建当前数组的一个副本,然后将接收到的参数添加到数组的末尾,然后返回新的数组。  
//如果没有给concat()方法传参数,则仅仅是复制当前数组并返回副本。  
//如果给concat()传递的是一个或者多个数组,则会将数组每一项都添加到结果数组中,  
//如果传递参数不是数组,则会简单地添加数组末尾。  
  
//var names = ["zhangsan","lisi"];  
//var names2 = names.concat('wangwu','zhaoliu',['xiaoming','xiangsun']);  
//alert(names); //zhangsan,lisi  
//alert(names2); // zhangsan,lisi,wangwu,zhaoliu,xiaoming,xiangsun  
  
  
//4、slice() : 基于当前数组的一项或多项创建新数组,接收一个或者两个参数,项的起始位置和结束位置。  
//slice方法不影响原始数组  
//var names = ["zhangsan","lisi","wangwu","zhaoliu","sunqi"];  
//var names2 = names.slice(1);  
//var names3 = names.slice(1,4); //包含起始位置元素,不包含结束位置元素  
//alert(names); //zhangsan,lisi,wangwu,zhaoliu,sunqi  
//alert(names2); //lisi,wangwu,zhaoliu,sunqi  
//alert(names3); //lisi,wangwu,zhaoliu  
  
//如果slice参数中有负数,则用数组长度加上该数来定位  
//var names = ["zhangsan","lisi","wangwu","zhaoliu","sunqi"];  
//alert(names.slice(-2,-1)); // slice(-2,-1) = slice(3,4)  返回 ”zhaoliu“  
  
//如果结束位置小于起始位置,则返回空数组  
//alert(names.slice(4,1)); //空数组  
  
  
//5、splice()方法:向数组中插入项,splice()方法始终返回一个数组,该数组包含从原始数组中删除的项,  
//如果没有删除任何项,则返回空数组。  
//(1):  删除数组项,从哪个位置开始删除,删除几项  
//var names = ["zhangsan","lisi","wangwu","zhaoliu","sunqi"];  
//alert(names.splice(0,2)); //zhangsan,lisi  
//alert(names); //wangwu,zhaoliu,sunqi  
  
//(2):  插入数组项,向指定位置插入任意数量的项。参数: 起始位置、0(要删除的项数)、要插入的项  
//var names = ["zhangsan","lisi","wangwu","zhaoliu","sunqi"];  
//var deleted = names.splice(1,0,'aa','bb','cc');  
//alert(names); //zhangsan,aa,bb,cc,lisi,wangwu,zhaoliu,sunqi  
//alert(deleted);//返回空数组  
  
//(3):  替换,向指定位置插入任意数量的项,且同时删除任意数量项,参数: 起始位置、要删除的项数)、要插入的项  
//var names = ["zhangsan","lisi","wangwu","zhaoliu","sunqi"];  
//var deleted = names.splice(1,1,'aa','bb','cc');  
//alert(names); //zhangsan,aa,bb,cc,wangwu,zhaoliu,sunqi  
//alert(deleted);//lisi  
  
  
//6、indexOf() \ lastIndexOf()  :  返回要查找项在数组中的位置,没找到返回-1,使用全等===比较  
//支持浏览器包含IE9+、其他浏览器  
//var names = ["zhangsan","lisi","wangwu","zhaoliu","sunqi","lisi","wangwu","sunqi"];  
//alert(names.indexOf("lisi")); // 1  
//alert(names.lastIndexOf("lisi")); // 5  
  
//7、数组遍历:every(),filter(),forEach(),map(),some()  参数:每一项上运行的函数,运行该函数的作用域对象  
//支持这些遍历方法的浏览器:IE9+及其他浏览器  
//every(): 遍历数组每一项,如果每一项都返回true,则返回true  
//some(): 遍历数组每一项,如果任意一项返回true,则返回true  
//filter(): 过滤满足条件的值,返回这些值组成的新数组  
//map() : 返回一个数组,这个数组的每一项都是在原始数组的对应项上运行传入函数的结果。  
//forEach(): 没有返回值,与for循环一样  
/* 
var numbers = [1,2,3,4,5,4,3,2,1]; 
var everyResult = numbers.every(function(item,index,array){ 
    return item > 2; 
}); 
alert(everyResult);  //false 
 
var someResult = numbers.some(function(item,index,array){ 
    return item > 2; 
}); 
alert(someResult);  //true 
 
var filterResult = numbers.filter(function(item,index,array){ 
    return item > 2; 
}); 
alert(filterResult);  //3,4,5,4,3 
 
var mapResult = numbers.map(function(item,index,array){ 
    return item*2; 
}); 
 
alert(mapResult);//2,4,6,8,10,8,6,4,2 
 
numbers.forEach(function(item,index,array){ 
    //TODO 
}); 
*/  
//8、reduce()\reduceRight(): 遍历数组所有项,构建一个最终返回值  
//reduce():  从前向后遍历,reduceRight() :从后项前遍历  
//接收四个参数: 前一个值,当前值,项索引,数组对象  
//函数返回值作为第一个参数自动传递给下一项。  
  
//使用reduce()求和  
var numbers = [1,2,3,4,5,6,7,8,9,10];  
var sum = numbers.reduce(function(prev,cur,index,array){  
    return prev + cur;  
});  
alert(sum); //55  

js 温习2

/* 
1、js数组跟其他语言的数组一样,都是数据的有序列表,但不同的是,js数组的每一项可以保存任何类型的数据。 
并且js数组的大小是可以动态调整的。 
 
2、创建数组方式: 
*/  
  
(1)使用Array构造函数创建数组:  
var names = new Array();  
  
创建length=30的数组  
var names = new Array(30); 如果预先知道数组长度,可直接传入数值   
alert(names.length);  30  
  
也可以像Array构造函数传递数组应该包含的项:  
var names2 = new Array("zhangsan","lisi","wangwu");  
alert(names2); zhangsan,lisi,wangwu  
  
给Array构造函数传递一个值也可以创建数组  
var ages = new Array(2);  创建包含两项的数组  
var ages = new Array("11"); 创建包含1项,即字符串“11”的数组  
  
可以省略new操作符  
var books = Array(2);创建包含两项的数组  
var books = Array("books1");创建包含1项,即字符串“books”的数组  
  
  
(2) 使用数组字面量表示法创建数组:数组字面量由一对包含数组项的方括号表示,多个数组项之间用逗号隔开  
var names = ["zhangsan","lisi","wangwu"];  创建一个包含3个字符串的数组  
var names = [];  创建一个空数组  
  
在数组最后一项添加逗号的结果:  
  
在其他浏览器中会创建包含2项且值分别为"zhangsan","lisi"的数组  
在IE中,names会创建包含3项,值分别为“zhangsan","lisi",undefined的数组,  
原因在于IE8及之前版本的ECMAScript实现在数组字面量方面存在BUG  
var names = ["zhangsan","lisi",];  
alert(names); IE9下报错,IE8及以下:zhangsan,lisi,  
alert(names.length);  
  
  
像这种省略值情况下,每一项都是undefined值。  
var names = [,,,,,];  
alert(names.length); 5:在及其他浏览器中创建包含5项的数组  
alert(names.length);   6:  在IE版本中创建包含6项的数组  
alert(names[5]); undefined  
  
  
读取设置数组值  
var colors = ["red","green","blue"];  
alert(colors[0]);  显示第一项  
colors[2] = "pink";  修改第三项  
alert(colors);  red,green,pink  
  
colors[3] = "black"; 增加第四项,设置某个值的索引超过了数组长度,则数组长度自动加1  
alert(colors); red,green,pink,black  
  
  
3、length属性:>=0  ,length属性不是只读的,可以通过设置length属性来从数组末尾移除项或向数组中添加项  
var colors = ["red","green","blue"];  
colors.length = 2;    
alert(colors[2]);  undefined  
  
var colors = ["red","green","blue"];  
colors.length = 4;    
alert(colors[3]);  undefined  
  
var colors = ["red","green","blue"];  
colors[colors.length] = "black";  
colors[colors.length] = "pink";  
alert(colors);  red,green,blue,black,pink  
  
var colors = ["red","green","blue"]  
colors[99] = "black";  
alert(colors.length);  100  ,colors[3]到color[98]都是undefined  
  
4、数组类型判断   
  
对于一个网页或一个全局作用域,instanceof假定单一的全局执行环境  
var colors = ["red","green","blue"];  
var obj = {};  
alert(colors instanceof Array); true  
alert(obj instanceof Array);  false  
  
对于网页中包含多个框架,则就存在多个不同的全局执行环境,从而存在多个不同版本的Array构造函数,  
那么从一个框架向另一个框架传入一个数组,则传入的数组与第二个框架中的数组则分别具有不同构造  
为了解决这个问题,则须采用Array.isArray()方法  
  
var colors = ["red", "green", "blue"];  
var obj = {};  
alert(Array.isArray(colors)); true  
alert(Array.isArray(obj)); false  
  
兼容性:支持isArray方法的浏览器有: IE9+,其他浏览器  
  
  
5、toString(): 返回数组每一项用逗号分隔的字符串,调用数组每一项的toString()方法  
valueOf(): 返回数组  
var colors = ["red", "green", "blue"];  
alert("toString="+colors.toString()); red,green,blue  
alert(colors); alert接收字符串参数,传递给它的是数组,因此在后头会调用Array的toString()方法  
alert("valueOf="+colors.valueOf());   
alert(Array.isArray(colors.valueOf())); true  
  
toLocaleString():  返回数组每一项用逗号分隔的字符串,调用每一项的toLocaleString()方法,而不是toString()方法  
/* 
var book1 = { 
    toString : function(){ 
        return "book1.toString()"; 
    }, 
 
    toLocaleString : function(){ 
        return "book1.toLocaleString()"; 
    } 
 
}; 
var book2 = { 
    toString : function(){ 
        return "book2.toString()"; 
    }, 
 
    toLocaleString : function(){ 
        return "book2.toLocaleString()"; 
    } 
 
}; 
var book = [book1,book2]; 
alert(book); book1.toString(),book2.toString() 
alert(book.toString); function toString(){[natice code]} 
alert(book.toString());book1.toString(),book2.toString() 
alert(book.toLocaleString());book1.toLocaleString(),book2.toLocaleString() 
*/  
  
join(): 接收一个作为分隔符的参数, 返回由分隔符分隔的字符串,  
var colors = ["red^", "green^", "blue^"];  
alert(colors.join(','));red^,green^,blue^  
alert(colors.join('|'));red^|green^|blue^  
alert(colors.join()); 默认以逗号分隔: red^,green^,blue^  
alert(colors.join(undefined));在IE8+及其他浏览器中显示:red^,green^,blue^  
alert(colors.join(undefined)); 在IE7及以下版本显示:red^undefinedgreen^undefinedblue^  
  
如果数组中的某一项值为null或undefined,则该值在join()\valueOf()\toString()\toLocaleString()都返回空字符串  
var names = ["zhangsan",null,undefined,"lisi"];  
alert(names); zhangsan,,,lisi  
  
  
push():  接收任意数量参数,添加到数组末尾,返回修改后数组长度  
var names = new Array();  
var num = names.push("zhangsan","lisi");  
alert(num); 2  
num = names.push("wangwu");  
alert(num); 3  
var item = names.pop();  
alert(item); wangwu  
  
shift() : 移除数组第一项并返回  
var colors = ["red","green","blue"];  
var item = colors.shift();  移除第一项并返回  
alert(item);  
alert(colors.length); 2  
  
unshift() : 在数组前端添加任意个项并返回数组新长度,对于IE7及更早版本,unshift返回undefined而不是数组长度  
var colors = ["red","green","blue"];  
var count = colors.unshift("aaa","bbb");  
alert(colors);"aaa","bbb","red","green","blue"  
alert(count);5  

几个开发的后台系统

第一个统一登录系统,因为时间有限,直接把本博客的后台系统精简然后实现的。很简陋。因为本身也不需要什么功能。

mobi-login.png

 

第二个一个恶意网址规则管理的,用的是Yii1框架写的。也是做了精简(我不喜欢一些没用的文件放在框架里面,虽然不影响什么效率,因为不加载不执行,但是看起来不顺眼)

wp_manager.png

»»阅读全文