zoukankan      html  css  js  c++  java
  • Node.js学习笔记(五) --- 使用Node.js搭建Web服务器

    1Node.js 创建的第一个应用

     1、引入http模块

    var http = require("http");

       2、 创建服务器
    接下来我们使用 http.createServer() 方法创建服务器,并使用 listen 方法绑定 8888 端口。函数通过 request, response 参数来接收和响应数据。

    //1.引入 http 模块
    var http=require('http');
    //2.用 http 模块创建服务
    http.createServer(function(req,res){
    // 发送 HTTP 头部
    // HTTP 状态值: 200 : OK
    //设置 HTTP 头部,状态码是 200,文件类型是 html,字符集是 utf-8
    res.writeHead(200,{"Content-Type":"text/html;charset='utf-8'"});
    res.write('你好 nodejs');
    res.write('我是第一个 nodejs 程序');
    res.end(); /*结束响应*/
    }).listen(8001);
    

      

       2WEB 服务器介绍
    Web 服务器一般指网站服务器,是指驻留于因特网上某种类型计算机的程序,可以向浏览器等 Web 客户端提供文档, 也可以放置网站文件,让全世界浏览;可以放置数据文件,让全世界下载。目前最主流的三个 Web 服务器是 Apache 、 Nginx 、IIS

       3Nodejs 封装一个 WEB 服务器

    启动
    node start
    功能
    * 能显示以 `.html/.htm` 结尾的 Web 页面
    
    * 能直接打开以 `.js/.css/.json/.text` 结尾的文件内容
    
    * 显示图片资源
    
    * 自动下载以 `.apk/.docx/.zip` 结尾的文件
    
    * 形如 `http://xxx.com/a/b/` , 则查找b目录下是否有 `index.html`,如果有就显示,如果没有就列出该目录下的所有文件及文件夹,并可以进一步访问。
    
    * 形如 `http://xxx.com/a/b`,  则作301重定向到 `http://xxx.com/a/b/` , 这样可以解决内部资源引用错位的问题。

    HttpServer.js

    module.exports = (function () {
    
      "use strict";
    
      console.time('[HttpServer][Start]');
    
      //http协议模块
      var http = require('http');
      //url解析模块
      var url = require('url');
      //文件系统模块
      var fs = require("fs");
      //路径解析模块
      var path = require("path");
    
      return {
        //启动服务
        start: function () {
          var port = this.config.port;
          var ip = this.config.ip;
    
          //创建一个服务
          var httpServer = http.createServer(this.processRequest.bind(this));
    
          //在指定的端口监听服务
          httpServer.listen(port, function () {
            console.log("[HttpServer][Start]", "runing at http://" + ip + ":" + port + "/");
            console.timeEnd("[HttpServer][Start]");
          });
    
          httpServer.on("error", function (error) {
            console.error(error);
          });
        },
    
        /**
         * 请求处理
         * @param request
         * @param response
         */
        processRequest: function (request, response) {
          var hasExt = true;
          var requestUrl = request.url;
          var pathName = url.parse(requestUrl).pathname;
    
          //对请求的路径进行解码,防止中文乱码
          pathName = decodeURI(pathName);
    
          //如果路径中没有扩展名
          if ((pathName) === '') {
            //如果不是以/结尾的,加/并作301重定向
            if (pathName.charAt(pathName.length - 1) != "/") {
              pathName += "/";
              var redirect = "http://" + request.headers.host + pathName;
              response.writeHead(301, {
                location: redirect
              });
              response.end();
              return; //fix bug: 执行301重定向后应终止后续流程,以防 "write after end" 异常
            }
            //添加默认的访问页面,但这个页面不一定存在,后面会处理
            pathName += "index.html";
            hasExt = false; //标记默认页面是程序自动添加的
          }
    
          //获取资源文件的相对路径
          var filePath = path.join("http/webroot", pathName);
    
          //获取对应文件的文档类型
          var contentType = this.getContentType(filePath);
    
          //如果文件名存在
          fs.exists(filePath, function (exists) {
            if (exists) {
              response.writeHead(200, {"content-type": contentType});
              var stream = fs.createReadStream(filePath, {flags: "r", encoding: null});
              stream.on("error", function () {
                response.writeHead(500, {"content-type": "text/html"});
                response.end("<h1>500 Server Error</h1>");
              });
              //返回文件内容
              stream.pipe(response);
            } else { //文件名不存在的情况
              if (hasExt) {
                //如果这个文件不是程序自动添加的,直接返回404
                response.writeHead(404, {"content-type": "text/html"});
                response.end("<h1>404 Not Found</h1>");
              } else {
                //如果文件是程序自动添加的且不存在,则表示用户希望访问的是该目录下的文件列表
                var html = "<head><meta charset='utf-8'></head>";
    
                try {
                  //用户访问目录
                  var filedir = filePath.substring(0, filePath.lastIndexOf('\'));
                  //获取用户访问路径下的文件列表
                  var files = fs.readdirSync(filedir);
                  //将访问路径下的所以文件一一列举出来,并添加超链接,以便用户进一步访问
                  for (var i in files) {
                    var filename = files[i];
                    html += "<div><a  href='" + filename + "'>" + filename + "</a></div>";
                  }
                } catch (e) {
                  html += "<h1>您访问的目录不存在</h1>"
                }
                response.writeHead(200, {"content-type": "text/html"});
                response.end(html);
              }
            }
          });
        },
    
        /**
         * 获取文档的内容类型
         * @param filePath
         * @returns {*}
         */
        getContentType: function (filePath) {
          var contentType = this.config.mime;
          var ext = path.extname(filePath).substr(1);
          if (contentType.hasOwnProperty(ext)) {
            return contentType[ext];
          } else {
            return contentType.default;
          }
        },
    
        ///配置信息
        config: {
          port: 8888,
          ip: '127.0.0.1',
          mime: {
            html: "text/html",
            js: "text/javascript",
            css: "text/css",
            gif: "image/gif",
            jpg: "image/jpeg",
            png: "image/png",
            ico: "image/icon",
            txt: "text/plain",
            json: "application/json",
            default: "application/octet-stream"
          }
        }
      }
    })();
    

    start.js

    var http = require('./http/HttpServer');
    http.start();

    源代码

     
  • 相关阅读:
    Android-调用优酷SDK上传视频
    新浪微博客户端(16)-获得并显示用户昵称
    新浪微博客户端(15)-保存用户名和密码
    转:Java NIO系列教程(九) Pipe
    新浪微博客户端(14)-截取回调地址中的授权成功的请求标记,换取access_token
    iOS-AFN "Request failed: unacceptable content-type: text/plain"
    新浪微博客户端(13)-使用UIWebView加载OAuth授权界面
    iOS-(kCFStreamErrorDomainSSL, -9802)
    转:Java NIO系列教程(八) DatagramChannel
    转:Java NIO系列教程(七) Socket Channel
  • 原文地址:https://www.cnblogs.com/chenyablog/p/9849719.html
Copyright © 2011-2022 走看看