原文:http://nqdeng.github.io/7-days-nodejs/
模块
require
require用于在当前模块中加载和使用别的模块,传入一个对象名,返回一个模块导出对象。模块名可以使用相对路径和绝对路径。(当用require调用模块时,无论模块被调用多少次,它只会被初始化一次。)
exports
exports对象是当前模块的导出对象,用于导出模块共有方法和属性。
exports.hello = function () {
console.log('Hello World!');
};
module
通过module对象可以访问到当前模块的一些相关信息,但最多的用途是替换当前模块的导出对象。
命令行程序
用命令行直接运行nodejs模块,首先将所在目录加入系统环境变量中,在此文件夹新建一个cmd文件,内容为完整的命令语句,比如:
@node "D:\wamp\www\7daynodejs\exports\app.js" %*
将文件命名为想要的名称后在命令行直接运行这个名称就可以执行了。
文件模块
中文API: http://nodejs.cn/api/fs
实现一简单的文件copy程序
var fs = require('fs');
function copy(src, dst) {
fs.writeFileSync(dst, fs.readFileSync(src));
}
function main(argv) {
copy(argv[0], argv[1]);
}
main(process.argv.slice(2));
在输入命令后加两个参数即可运行
eg:
node copyFile.js app.js app_copy.js
process是一个全局变量,可通过process.argv获得命令行参数。由于argv[0]固定等于NodeJS执行程序的绝对路径,argv[1]固定等于主模块的绝对路径,因此第一个命令行参数从argv[2]这个位置开始。
拷贝小文件时这个方法没问题,当拷贝大文件时这种一次性把所有文件内容都读取到内存中后再一次性写入磁盘的方式就不适合了。改造后的程序如下:
var fs = require('fs');
function copy(src, dst) {
fs.createReadStream(src).pipe(fs.createWriteStream(dst));
}
function main(argv) {
copy(argv[0], argv[1]);
}
main(process.argv.slice(2));
以上程序使用fs.createReadStream创建了一个源文件的只读数据流,并使用fs.createWriteStream创建了一个目标文件的只写数据流,并且用pipe方法把两个数据流连接了起来。连接起来后发生的事情,说得抽象点的话,水顺着水管从一个桶流到了另一个桶。
遍历目录示例
var fs=require('fs');
var path=require('path');
var thisDir=process.argv[1].substr(0,process.argv[1].lastIndexOf('\\'));
function travel(thisDir){
console.log(thisDir);
fs.readdirSync(thisDir).forEach(function(file){
var pathname=path.join(thisDir, file);
console.log(' '+path.join(thisDir, file));
if(fs.statSync(pathname).isDirectory())
{
travel(pathname);
}
});
}
travel(thisDir);
网络编程
创建简单web服务器 hello world
var http = require('http');
http.createServer(function (request, response) {
response.writeHead(200, { 'Content-Type': 'text-plain' });
response.end('Hello World\n');
}).listen(8124);
获取网络数据。
实例:客户端显示最新知乎日报json数据
var http = require('http');
http.createServer(function (request, response) {
var body = [];
http.get('http://news.at.zhihu.com/api/1.2/news/latest', function (res) {
res.on('data', function (chunk) {
body.push(chunk);
});
res.on('end',function(){
response.writeHead(200, {'Content-Type': 'text/html;charset=utf-8'});
// response.write(body.toString());
response.end(body.toString());
});
});
}).listen(8123)
console.log('HELLOWORLD is running')
url模块
该模块允许解析URl生成URL,以及拼接URL。
完整url组成部分:
.parse方法可以将一个url字符串转化为URL对象,示例如下:
url.parse('http://user:pass@host.com:8080/p/a/t/h?query=string#hash');
/* =>
{ protocol: 'http:',
auth: 'user:pass',
host: 'host.com:8080',
port: '8080',
hostname: 'host.com',
hash: '#hash',
search: '?query=string',
query: 'query=string',
pathname: '/p/a/t/h',
path: '/p/a/t/h?query=string',
href: 'http://user:pass@host.com:8080/p/a/t/h?query=string#hash' }
*/
.parse方法还支持第二个和第三个布尔类型可选参数。第二个参数等于true时,该方法返回的URL对象中,query字段不再是一个字符串,而是一个经过querystring模块转换后的参数对象。第三个参数等于true时,该方法可以正确解析不带协议头的URL,例如//www.example.com/foo/bar。
反过来,format方法允许将一个URL对象转换为URL字符串,示例如下。
url.format({
protocol: 'http:',
host: 'www.example.com',
pathname: '/p/a/t/h',
search: 'query=string'
});
/* =>
'http://www.example.com/p/a/t/h?query=string'
*/
另外,.resolve方法可以用于拼接URL,示例如下。
url.resolve('http://www.example.com/foo/bar', '../baz');
/* =>
http://www.example.com/baz
*/
querystring模块
querystring.parse('foo=bar&baz=qux&baz=quux&corge');
/* =>
{ foo: 'bar', baz: ['qux', 'quux'], corge: '' }
*/
querystring.stringify({ foo: 'bar', baz: ['qux', 'quux'], corge: '' });
/* =>
'foo=bar&baz=qux&baz=quux&corge='
*/