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

文件路径示意:

C:\Users\Administrator\我的文档\HBuilderProject\httpServer


httpServer:
│  app.js
│  
└─HS\
    │  httpServer.html   // 主页面
    │  
    ├─css
    │      test.css
    │      
    ├─imgs
    │      img.jpg 
    │      
    └─js
            test.js        
初涉Node:搭建一个简单的node服务器_第1张图片

静态资源内容:

httpServer.html




    
    Document
    


    

Hello World!

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('

404 Not Found

') } 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.........

初涉Node:搭建一个简单的node服务器_第2张图片
QQ截图20180421171034.jpg

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

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

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

每一次请求的pathObj如下:

初涉Node:搭建一个简单的node服务器_第3张图片
'/httpServer.html'
初涉Node:搭建一个简单的node服务器_第4张图片
'/css/test.css'
初涉Node:搭建一个简单的node服务器_第5张图片
'/imgs/img.jpg'
初涉Node:搭建一个简单的node服务器_第6张图片
'/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('

404 Not Found

') } 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服务器)