设为首页 - 加入收藏 核心网 (http://www.hxwgxz.com)- 云主机,资讯,互联网,人工智能,云计算,大数据,区块链,VR,站长网!
热搜: 市场 系统 统一 2017
当前位置: 主页 > 业界 > 正文

Node.js 原生 api 搭建 web 服务器

发布时间:2019-02-16 07:08 所属栏目:[业界] 来源:想不起来了
导读:node.js 实现一个简单的 web 服务器还是比较简单的,以前利用 express 框架实现过『nodeJS搭一个简单的(代理)web服务器』。代码量很少,可是使用时需要安装依赖,多处使用难免有点不方便。于是便有了完全使用原生 api 来重写的想法,也当作一次 node.js 复

node.js 实现一个简单的 web 服务器还是比较简单的,以前利用 express 框架实现过『nodeJS搭一个简单的(代理)web服务器』。代码量很少,可是使用时需要安装依赖,多处使用难免有点不方便。于是便有了完全使用原生 api 来重写的想法,也当作一次 node.js 复习。

Node.js 原生 api 搭建 web 服务器

1、静态 web 服务器

  1. 'use strict' 
  2.  
  3. const http = require('http') 
  4. const url = require('url') 
  5. const fs = require('fs') 
  6. const path = require('path') 
  7. const cp = require('child_process') 
  8.  
  9. const port = 8080 
  10. const hostname = 'localhost' 
  11.  
  12. // 创建 http 服务 
  13. let httpServer = http.createServer(processStatic) 
  14. // 设置监听端口 
  15. httpServer.listen(port, hostname, () => {   
  16.   console.log(`app is running at port:${port}`)   
  17.   console.log(`url: http://${hostname}:${port}`) 
  18.   cp.exec(`explorer http://${hostname}:${port}`, () => {}) 
  19. }) 
  20. // 处理静态资源 
  21. function processStatic(req, res) {   
  22.   const mime = { 
  23.     css: 'text/css', 
  24.     gif: 'image/gif', 
  25.     html: 'text/html', 
  26.     ico: 'image/x-icon', 
  27.     jpeg: 'image/jpeg', 
  28.     jpg: 'image/jpeg', 
  29.     js: 'text/javascript', 
  30.     json: 'application/json', 
  31.     pdf: 'application/pdf', 
  32.     png: 'image/png', 
  33.     svg: 'image/svg+xml', 
  34.     woff: 'application/x-font-woff', 
  35.     woff2: 'application/x-font-woff', 
  36.     swf: 'application/x-shockwave-flash', 
  37.     tiff: 'image/tiff', 
  38.     txt: 'text/plain', 
  39.     wav: 'audio/x-wav', 
  40.     wma: 'audio/x-ms-wma', 
  41.     wmv: 'video/x-ms-wmv', 
  42.     xml: 'text/xml' 
  43.   }   
  44.   const requestUrl = req.url   
  45.   let pathName = url.parse(requestUrl).pathname   
  46.   // 中文乱码处理 
  47.   pathName = decodeURI(pathName)   
  48.   let ext = path.extname(pathName)   
  49.   // 特殊 url 处理 
  50.   if (!pathName.endsWith('/') && ext === '' && !requestUrl.includes('?')) { 
  51.     pathName += '/' 
  52.     const redirect = `http://${req.headers.host}${pathName}` 
  53.     redirectUrl(redirect, res) 
  54.   }   
  55.   // 解释 url 对应的资源文件路径 
  56.   let filePath = path.resolve(__dirname + pathName)   
  57.   // 设置 mime  
  58.   ext = ext ? ext.slice(1) : 'unknown' 
  59.   const contentType = mime[ext] || 'text/plain' 
  60.  
  61.   // 处理资源文件 
  62.   fs.stat(filePath, (err, stats) => {     
  63.     if (err) { 
  64.       res.writeHead(404, { 'content-type': 'text/html;charset=utf-8' }) 
  65.       res.end('<h1>404 Not Found</h1>')       
  66.       return 
  67.     }     
  68.     // 处理文件 
  69.     if (stats.isFile()) { 
  70.       readFile(filePath, contentType, res) 
  71.     }     
  72.     // 处理目录 
  73.     if (stats.isDirectory()) {       
  74.       let html = "<head><meta charset = 'utf-8'/></head><body><ul>" 
  75.       // 遍历文件目录,以超链接返回,方便用户选择 
  76.       fs.readdir(filePath, (err, files) => {         
  77.         if (err) { 
  78.           res.writeHead(500, { 'content-type': contentType }) 
  79.           res.end('<h1>500 Server Error</h1>') 
  80.           return 
  81.         } else {           
  82.           for (let file of files) {             
  83.             if (file === 'index.html') {               
  84.               const redirect = `http://${req.headers.host}${pathName}index.html` 
  85.               redirectUrl(redirect, res) 
  86.             } 
  87.             html += `<li><a href='${file}'>${file}</a></li>` 
  88.           } 
  89.           html += '</ul></body>' 
  90.           res.writeHead(200, { 'content-type': 'text/html' }) 
  91.           res.end(html) 
  92.         } 
  93.       }) 
  94.     } 
  95.   }) 
  96. // 重定向处理 
  97. function redirectUrl(url, res) { 
  98.   url = encodeURI(url) 
  99.   res.writeHead(302, { 
  100.     location: url 
  101.   }) 
  102.   res.end() 
  103. // 文件读取 
  104. function readFile(filePath, contentType, res) { 
  105.   res.writeHead(200, { 'content-type': contentType }) 
  106.   const stream = fs.createReadStream(filePath) 
  107.   stream.on('error', function() { 
  108.     res.writeHead(500, { 'content-type': contentType }) 
  109.     res.end('<h1>500 Server Error</h1>') 
  110.   }) 
  111.   stream.pipe(res) 

【免责声明】本站内容转载自互联网,其相关言论仅代表作者个人观点绝非权威,不代表本站立场。如您发现内容存在版权问题,请提交相关链接至邮箱:bqsm@foxmail.com,我们将及时予以处理。

网友评论
推荐文章