nodejs review-02

30 Receive POST data

  • POST接受JSON数据处理;
//req. res都是可读的stream;

http.createServer(function (req, res) {
  var json_data = '';

  req.on('readable', function () {
    var d = req.read();

    if(typeof d === 'string') {
      json_data += d;
    } else if(typeof d === 'object' && d instanceof Buffer) {      //可以简化使用Buffer.isBuffer/util.isBuffer判断;
      json_data += d.toString('utf8');
    }
  });

  req.on('end', function () {
    var out = '';

    if(!json_data) {
      out = 'No JSON';
    } else {
      var json;
      try {
        json = JSON.parse(json_data);       //判断是否为字符串化的JSON数据
      } catch(e) {}

      if(!json) out = 'Invalid JSON';
      else out = 'Valid Data JSON: ' + json_data;
    }
    res.end(out);
  });
}).listen(3000);

//curl的post

curl -i -X POST -H 'Content-Type: application/json' -d '{"name": "jinks" , "age": 25}' http://localhost:3000
  • POST接受query处理
var qs = require('querystring');
...
req.on('end', function () {
    var out = '';
    if(!form_data) {
      out = 'No JSON';
    } else {
      var json = qs.parse(form_data);
      if(!json) out = 'Invalid form_data';
      else out = 'Valid Data form_data: ' + JSON.stringify(json);
    }
    res.end(out);
  });
...

//--data 即 -d

curl -i -X POST  --data 'name=jinks&age=25' http://localhost:3000
  • 处理查询字符串的注意:如果同一个键有多个值,其值会以数组形式返回,实际业务中需要做判断

32 Use npm the node package manager

  • npm查找包
npm search
  • npm全局安装的地方/nodejs最底层查找包的地方;
/usr/local/lib/node_modules
  • 包映射
npm link;       //允许后将当前包映射到/usr/local/lib/node_modules中,每次当前包变化,相应机会变化;
npm link package;   //可以将/usr/local/lib/node_modules中的包映射到当前node_modules中,也会相应变化;

37 Investigate Node js streams

  • 读取数据流
var ws = fs.createWriteStream('test.js');

function read_file(filename, callback) {
  var rs = fs.createReadStream(filename);
  var content = '';

  rs.on('readable', function () {
    var d = rs.read();
    if(typeof d === 'string') {
          content += b;
    } else if(Buffer.isBuffer(d)) {
          content += d.toString('utf8')
    }
  });

  rs.on('end', function () {
        callback(null, content);
  });
};

read_file('example.txt', function (err, contents) {
  if(err) return console.log(err);
  return ws.write(contents);
});


//扩展
//1.使用data事件取代readable

 rs.on('data', function (chunk) {
    content += chunk.toString('utf8');
  });

//2.将全部读取完后写入改成边写边读

function read_file(filename, callback) {
  var rs = fs.createReadStream(filename);
  var content = '';

  rs.on('data', function (chunk) {
    ws.write(chunk) === false && rs.pause();
  });

  rs.on('end', function () {
        ws.end();
  });

  ws.on('drain', function () {
    rs.resume();
  });
  
  rs.on('err', function () {
        callback(err);
  });

  ws.on('err', function () {
    callback(err);
  });
};

//3.使用pipe
fs.createReadStream('example.txt')
  .pipe(fs.createWriteStream('copy.txt'))
  .on('error', function () {});
  • string,buffer的长度关系
var b = new Buffer(100);
var s = 'string';
b.write(s);
console.log(s.length, b.length, Buffer.byteLength(s)); //6, 100, 6

var b2 = new Buffer(100);
var c = '字符串';
b2.write(c);
console.log(c.length, b2.length, Buffer.byteLength(c));  //3, 100, 9

38 Serve static files from our server

  • server中使用数据库
http.createServer(function (req, res) {
  var rs = fs.createReadStream('example.txt');
  rs.on('error', function (err) {
      res.writeHead(404);
      res.end(JSON.stringify(err));
    })
    .on('open', function () {
      res.writeHead(202);
    })
    .on('data', function (chunk) {
      res.write(chunk) === false && rs.pause();
    })
    .on('drain', function () {
      rs.resume();
    })
    .on('end', function () {
      res.end();
    });
 }).listen(3000);

//
http.createServer(function (req, res) {
  var rs = fs.createReadStream('example.txt');
    rs.on('error', function (err) {
      res.writeHead(404);
      res.end(JSON.stringify(err));
    });
    rs.on('open', function () {
      res.writeHead(202);
    });
    rs.pipe(res);
}).listen(3000);

  • Buffer类型的处理
//
var fs = require('fs');
var rs = fs.createReadStream('example.txt');
var data = '';
rs.on("data", function (chunk){ 
  data += chunk;               //隐藏操作data = data.toString() + chunk.toString();
 });
rs.on("end", function () { 
  console.log(data);
});

//对于中文处理
rs.setEncoding('utf8');    //初始化声明;而然存在问题

//Buffer拼接
var chunks = [], size = 0;
res.on('data', function (chunk) {
  chunks.push(chunk);
  size += chunk.length;
};

res.on('end', function () {
  var buf = Buffer.concat(chunks, size);      //省略第二个参数时,Node内部会计算出这个值,然后再据此进行合并运算。因此,显式提供这个参数,能提供运行速度。
  console.log(buf.toString('utf8'));
});

//相当于
res.on('end', function () {
  var buffer = new Buffer(size), pos = 0;
  for(var i = 0, l = chunks.length; i < l; i++) {
    var buf = chunks[i];
    buf.copy(buffer, pos);
    pos += buf.length;
  };
  console.log(buffer.toString('utf8'));
});