副标题[/!--empirenews.page--]
node.js 实现一个简单的 web 服务器还是比较简单的,以前利用 express 框架实现过『nodeJS搭一个简单的(代理)web服务器』。代码量很少,可是使用时需要安装依赖,多处使用难免有点不方便。于是便有了完全使用原生 api 来重写的想法,也当作一次 node.js 复习。
1、静态 web 服务器
- 'use strict'
-
- const http = require('http')
- const url = require('url')
- const fs = require('fs')
- const path = require('path')
- const cp = require('child_process')
-
- const port = 8080
- const hostname = 'localhost'
-
- // 创建 http 服务
- let httpServer = http.createServer(processStatic)
- // 设置监听端口
- httpServer.listen(port, hostname, () => {
- console.log(`app is running at port:${port}`)
- console.log(`url: http://${hostname}:${port}`)
- cp.exec(`explorer http://${hostname}:${port}`, () => {})
- })
- // 处理静态资源
- function processStatic(req, res) {
- const mime = {
- css: 'text/css',
- gif: 'image/gif',
- html: 'text/html',
- ico: 'image/x-icon',
- jpeg: 'image/jpeg',
- jpg: 'image/jpeg',
- js: 'text/javascript',
- json: 'application/json',
- pdf: 'application/pdf',
- png: 'image/png',
- svg: 'image/svg+xml',
- woff: 'application/x-font-woff',
- woff2: 'application/x-font-woff',
- swf: 'application/x-shockwave-flash',
- tiff: 'image/tiff',
- txt: 'text/plain',
- wav: 'audio/x-wav',
- wma: 'audio/x-ms-wma',
- wmv: 'video/x-ms-wmv',
- xml: 'text/xml'
- }
- const requestUrl = req.url
- let pathName = url.parse(requestUrl).pathname
- // 中文乱码处理
- pathName = decodeURI(pathName)
- let ext = path.extname(pathName)
- // 特殊 url 处理
- if (!pathName.endsWith('/') && ext === '' && !requestUrl.includes('?')) {
- pathName += '/'
- const redirect = `http://${req.headers.host}${pathName}`
- redirectUrl(redirect, res)
- }
- // 解释 url 对应的资源文件路径
- let filePath = path.resolve(__dirname + pathName)
- // 设置 mime
- ext = ext ? ext.slice(1) : 'unknown'
- const contentType = mime[ext] || 'text/plain'
-
- // 处理资源文件
- fs.stat(filePath, (err, stats) => {
- if (err) {
- res.writeHead(404, { 'content-type': 'text/html;charset=utf-8' })
- res.end('<h1>404 Not Found</h1>')
- return
- }
- // 处理文件
- if (stats.isFile()) {
- readFile(filePath, contentType, res)
- }
- // 处理目录
- if (stats.isDirectory()) {
- let html = "<head><meta charset = 'utf-8'/></head><body><ul>"
- // 遍历文件目录,以超链接返回,方便用户选择
- fs.readdir(filePath, (err, files) => {
- if (err) {
- res.writeHead(500, { 'content-type': contentType })
- res.end('<h1>500 Server Error</h1>')
- return
- } else {
- for (let file of files) {
- if (file === 'index.html') {
- const redirect = `http://${req.headers.host}${pathName}index.html`
- redirectUrl(redirect, res)
- }
- html += `<li><a href='${file}'>${file}</a></li>`
- }
- html += '</ul></body>'
- res.writeHead(200, { 'content-type': 'text/html' })
- res.end(html)
- }
- })
- }
- })
- }
- // 重定向处理
- function redirectUrl(url, res) {
- url = encodeURI(url)
- res.writeHead(302, {
- location: url
- })
- res.end()
- }
- // 文件读取
- function readFile(filePath, contentType, res) {
- res.writeHead(200, { 'content-type': contentType })
- const stream = fs.createReadStream(filePath)
- stream.on('error', function() {
- res.writeHead(500, { 'content-type': contentType })
- res.end('<h1>500 Server Error</h1>')
- })
- stream.pipe(res)
- }
(编辑:南京站长网)
【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!
|