美文网首页
初涉Node:搭建一个简单的node服务器

初涉Node:搭建一个简单的node服务器

作者: DHFE | 来源:发表于2018-04-21 21:07 被阅读10次

    文件路径示意:

    C:\Users\Administrator\我的文档\HBuilderProject\httpServer
    
    
    httpServer:
    │  app.js
    │  
    └─HS\
        │  httpServer.html   // 主页面
        │  
        ├─css
        │      test.css
        │      
        ├─imgs
        │      img.jpg 
        │      
        └─js
                test.js        
    

    静态资源内容:

    httpServer.html

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Document</title>
        <link rel="stylesheet" href="css/test.css">
    </head>
    <body>
        <h1>Hello World!</h1>
        <img src="imgs/img.jpg">
    </body>
    <script src="js/test.js"></script>
    </html>
    </html>
    

    test.css

    h1 {
        color: skyblue;
    }
    

    test.js

    alert("sss");
    

    img
    一张图


    静态服务器实现大致思路:

    浏览器发送URL,服务端解析URL,对应到硬盘上的文件。如果文件存在,返回200状态码,并发送文件到浏览器端;如果文件不存在,返回404状态码,发送一个404的文件到浏览器端。

    app.js
    var http = require('http')
    var path = require('path')
    var fs = require('fs')
    var url = require('url')
    
    function staticRoot(staticPath, req, res) {
    
      console.log("staticPath: " + staticPath);
    
      console.log("req.url: " + req.url);           // 查看请求URL
      var pathObj = url.parse(req.url, true);
      console.log(pathObj);                         // 使用URL模块的功能函数解析请求URL,得到相关对象
    
      if (pathObj.pathname === '/') {
        pathObj.pathname += 'httpServer.html'
      }
    
      var filePath = path.join(staticPath, pathObj.pathname);         // 拼装为各资源文件绝对路径
      // c:\Users\Administrator\我的文档\HBuilderProject\httpServer\HS + ['httpServer.html','/css/test.css','/imgs/img.jpg','/js/test.js']
      console.log("filePath: " + filePath);
    
      
      fs.readFile(filePath, 'binary', function (err, fileContent) {  
        if (err) {
          console.log('404')
          res.writeHead(404, 'not found')
          res.end('<h1>404 Not Found</h1>')
        } else {
          console.log('ok');
          res.writeHead(200, 'OK');
          res.write(fileContent, 'binary');
          res.end();
        }
      });
      
    
      console.log("\n");
    }
    
    var server = http.createServer(function (req, res) {
      staticRoot(path.join(__dirname, 'HS'), req, res);             // 将其组装成资源文件夹路径
      // c:\Users\Administrator\我的文档\HBuilderProject\httpServer\ + HS
    })
    server.listen(8080);
    console.log('visit http://localhost:8080');
    

    访问localhost:8080,将会进入createServer函数,参数req res包括了浏览器的请求信息和响应信息(head),我们用一个staticRoot函数来接受并处理后续内容。

    参数__dirname为app.js所在绝对路径的文件夹。
    c:\Users\Administrator\我的文档\HBuilderProject\httpServer
    使用join()方法,拼接静态资源内容所在文件夹。
    // c:\Users\Administrator\我的文档\HBuilderProject\httpServer\HS

    此时,本地服务器便可根据绝对路径找到相关静态文件,发送出去。

    接下来需要解析请求URL。
    console.log("req.url: " + req.url);
    在我们传入staticRoot函数中的req对象包含了许多请求信息,如User-Agent、cookie、accept、host、method.........

    QQ截图20180421171034.jpg

    url.parse()可以将一个完整的URL地址,分为很多部分,常用的有:host、port、pathname、path、query。

    var pathObj = url.parse(req.url, true);
    

    我们可以从req对象里得到用户的请求URL,其实就是文件的路径。

    每一次请求的pathObj如下:

    '/httpServer.html' '/css/test.css' '/imgs/img.jpg' '/js/test.js'
    var filePath = path.join(staticPath, pathObj.pathname);
    

    拼接为绝对路径。

    请求URL:
    c:\Users\Administrator\我的文档\HBuilderProject\httpServer\HS\httpServer.html
    c:\Users\Administrator\我的文档\HBuilderProject\httpServer\HS\css\test.css
    c:\Users\Administrator\我的文档\HBuilderProject\httpServer\HS\imgs\img.jpg
    c:\Users\Administrator\我的文档\HBuilderProject\httpServer\HS\js\test.js

    进入下面的函数。

      fs.readFile(filePath, 'binary', function (err, fileContent) {   // 这个函数只执行了一次
        test++;
        if (err) {
          console.log('404')
          res.writeHead(404, 'not found')
          res.end('<h1>404 Not Found</h1>')
        } else {
          console.log('ok');
          res.writeHead(200, 'OK');
          res.write(fileContent, 'binary');
          res.end();
        }
      });
    

    关于fs模块:

    Node.js 文件系统
    Node.js——文件系统模块

    异步读取时,传入的回调函数接收两个参数,当正常读取时,err参数为nullfileContent参数为读取到的String。当读取发生错误时,err参数代表一个错误对象,fileContentundefined。这也是Node.js标准的回调函数:第一个参数代表错误信息,第二个参数代表结果。

    res.writeHead()

    向请求的客户端发送响应头。
    该函数在一个请求内最多只能调用一次,如果不调用,则会自动生成一个响应头。

    response.writeHead(statusCode, [reasonPhrase], [headers])
    // statusCode:响应头的状态码,如:200、404等
    // reasonPhase:[可选],用于简单说明的字符串。比如:“服务器因为维护暂时无法正常访问....”
    // headers:类似关联数组的对象,表示响应头的每个属性
    
    res.write()

    向请求的客户端发送响应内容。
    在 response.end() 之前,response.write() 可以被执行多次。

    response.write(chunk, [encoding])
    // chunk:一个buffer 或 字符串,表示发送的内容
    // encoding:如果chunk是字符串,就需要指定encoding来说明它的编码方式,默认utf-8
    
    res.end()

    结束响应,告诉客户端所有消息已经发送。当所有要返回的内容发送完毕时,该函数必须被调用一次。
    如何不调用该函数,客户端将永远处于等待状态

    response.end([data], [encoding])
    // data:end()执行完毕后要输出的字符,如果指定了 data 的值,那就意味着在执行完 response.end() 之后,会接着执行一条 response.write(data , encoding);
    // encoding:对应data的字符编码
    
    

    所有资源读取返回客户端后,将先弹出对话框,然后显示页面。

    相关文章

      网友评论

          本文标题:初涉Node:搭建一个简单的node服务器

          本文链接:https://www.haomeiwen.com/subject/zfytlftx.html