nodejs 5 nodejs的web应用-http服务器(http, 路由,get,post,https)

介绍node.js的web应用,主要包括HTTP服务器、Node.js静态资源管理、Node.js的文件处理功能、Cookie和Session的应用、Node.js安全加密,最后介绍Node.js如何与Nginx搭档。

案例:文字直播Web应用

1. 用户: 直播员(登录), 游客。
2. 直播方式:直播员登录后台,输入相应的的直播信息(图片和文字)。
3. 技术统计: 在线实时记录运动员数据。
4. 游客套路: 游客实时进行在线讨论。
5. 微博分享: 游客通过腾讯微博和新浪微博分享直播内容。

1.简单的HTTP服务器

var http = require("http"),
  fs = require("fs"),
  url = require("url");

/*创建http服务器*/
http.createServer(function (req, res) {
  /**胡获取Web客户端请求路径 */
  var pathName = url.parse(req.url).pathname;
  /**打印客户端请求req对象中的url、method、headers属性 */
  console.log("url: ", req.url);
  console.log("method: ", req.method);
  console.log("headers: ", req.headers);
  console.log('pathName',pathName)
  /**根据pathName,路由调用不同处理逻辑 */
  switch (pathName) {
    case "/index": resIndex(res); //响应HTML页面到Web客户端
      break;
    case "/img": resImage(res); //响应图片数据到Web客户端
      break;
    default: resDefault(res); //响应文字信息到Web客户端
      break;
  }
}).listen(3000);
console.log('Server running at http://127.0.0.1:3000/');

function resIndex(res) {
  var readPath = __dirname + "/" + url.parse("index.html").pathname;
  var indexPage  = fs.readFileSync(readPath);
  res.writeHead(200, { "Content-Type": "text/html" });
  res.end(indexPage);
}

function resImage(res){
  var readPath = __dirname + "/" + url.parse("logo.jpg").pathname;
  var indexPage  = fs.readFileSync(readPath);
  res.writeHead(200, { "Content-Type": "image/jpg" });
  res.end(indexPage);
}

function resDefault(res){
  res.writeHead(404, { "Content-Type": "text/plain" });
  res.end('can not find source');
}

运行结果如下图:依次为请求’/’ , ‘/index’ , ‘img’的返回结果

image

image

image


2.路由处理

虽然用switch可以解决路由问题,但是。。如果请求资源非常复杂时,那个代码量可以想象。。简直灾难。所以。。

  1. 特定规则请求路径

    根据用户请求的url,依据特定的规则得到相应的执行方法。

    请求’/index’ => resIndex(req, res)
    请求’/img’ => resImg(req, res)

    var response = "";
    var param = pathname.substr(2),
    //获取客户端请求的url路径,并获取其第一个参数,将其小写转为大写
    firstParam = param.substr(1, 1).toUpperCase();
    var functionName = 'res' + firstParam + param;
    response = res;
    if(pathname == "/") {
      resDefault(res);
    } else if (pathname == "/favicon.ico") {
      return;
    } else {
      eval(functionName + '()');
    }

    注意: 此方法的参数res, req必须设置为全局变量!!!

  2. 利用附带参数来实现路由处理

    url路径指定需要执行的模块,通过在HTTP的url中携带一个C参数,表示需要调用的模块中的方法名。

    如: ‘/image?c=img’ 表示获取index模块中img方法

    
    //client.js
    var http = require("http"),
      url = require("url"),
      querystring = require("querystring");
    
    http.createServer(function(req, res) {
      var pathname = url.parse(req.url).pathname;
      if(pathname == '/favicon.ico') { //请求favicon.ico
        return;
      }
      /**根据用户请求的url路径,截取其中的module和controller */
      var module = pathname.substr(1),
        str = url.parse(req.url).query,
        controller = querystring.parse(str).c,
        classObj = "";
      //应用try catch来require一个模块,并捕获异常
      try {    
        classObj = require("./" + module);
      } catch (err) {
        console.log("chdir: " + err);
      }
      //require 成功时,调用call方法,实现类中的方法调用执行
      if(classObj) {
        classObj.init(req, res);
        classObj[controller].call();
      } else {
        //调用不存的模块是,默认返回404错误信息
        res.writeHead("404", {"Content-Type": "text/plain"});
        res.end("can not find source");
      }
    }).listen(3000);
    console.log('Server running at http://127.0.0.1:3000/');
    
    //index.js
    var req, res,
      fs = require("fs"),
      url = require("url");
    
    /**创建初始变量函数 */
    exports.init = function(request, response){
      req = request;
      res = response;
    }
    /**创建index首页函数 */
    exports.index = function() {
      var readPath = __dirname + "/" + url.parse("index.html").pathname;
      var indexPage  = fs.readFileSync(readPath);
      res.writeHead(200, { "Content-Type": "text/html" });
      res.end(indexPage);
    }
    
    //image.js
    var req, res,
      fs = require("fs"),
      url = require("url");
    
    /**创建初始变量函数 */
    exports.init = function(request, response){
      req = request;
      res = response;
    }
    /**创建index首页函数 */
    exports.img = function() {
       var readPath = __dirname + "/" + url.parse("logo.jpg").pathname;
      var indexPage  = fs.readFileSync(readPath);
      res.writeHead(200, { "Content-Type": "image/jpg" });
      res.end(indexPage);
    }
    

    运行:这个时候路由链接应该为’/index?c=index’ 或 ‘/image?c=img’


3.GET和POST

  1. GET

    GET请求: http://localhost:3000/test?name=zula&book=nodejs

    url.parse(req.url).pathname => test?name=zula

    url.parse(req.url).query => name=zula&book=nodejs

    querystring.parse("name=zula&book=nodejs") => {name: “zula”, book: “nodejs”}

    实例

    使用http模块创建一个服务器,接收任意的url请求资源,使用GET方法传递参数,输出每次请求的路径名和请求参数的json对象。

    //get_method.js
    var http = require("http"),
      url = require("url"),
      querystring = require("querystring");
    http.createServer(function(req, res) {
      var pathname = url.parse(req.url).pathname, //获取请求路径
        paramStr = url.parse(req.url).query, //获取url请求参数
        param = querystring.parse(paramStr); //将url请求参数转为json对象
    
      if("/favicon.ico" == pathname) {
        return;
      }
      console.log("pathname: ", pathname );
      console.log("paramStr: " , paramStr || "no params" );
      console.log("param: " , param );
      res.writeHead(200, {'Content-type': 'text/plain'});
      res.end("success");
    }).listen(3000);
    console.log('Server running at http://127.0.0.1:3000/');

    运行结果:

    依次为 的运行结果

    http://localhost:3000

    http://localhost:3000/11

    http://localhost:3000/11?name=zula&age=18

    image

  2. POST

    post请求一般较为复杂,一般将post数据拆分为很多小的数据块,通过触发特定的事件,将这些小数据块有序传递给回调函数。addListener(“data”)传输开始和addListener(“end”)传输结束。

    实例

    var http      = require("http");
     querystring = require("querystring");
    var server = http.createServer(function (req,res) {
      var postData = "";
      /*接受客户端post的数据*/
      req.addListener("data", function(postDataChunk) {
        postData += postDataChunk;
      })
      /*数据接收完成后执行匿名回调函数*/
      req.addListener("end", function() {
        var postStr = JSON.stringify(querystring.parse(postData));
        res.writeHead(200,{'Content-Type':'text/plain'});
        res.end(postStr + "\n" + req.method);
      })
    }).listen(3000,"127.0.0.1");
    console.log('Server running at http://127.0.0.1:3000/');

    运行结果:

    image

    image

  3. httpParams

    var _req, _res,
      url = require("url"),
      querystring = require("querystring");
    
    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] || "";
    }
    
    /**获取post参数方法 */
    exports.POST = function(key, callback) {
      var postData = "";
      _req.addListener("data", function(postDataChunk) {
        postData += postDataChunk;
      })
      _req.addListener("end", function() {
        var param = querystring.parse(postData);
        var value = params[key] || "";
        callback(value);
      })
    }
  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值