zoukankan      html  css  js  c++  java
  • nodejs 学习笔记(四)—— 搭建静态Web服务器

    在学习笔记(一)里我们已经搭建过一个最简单的服务器,但这个服务器只能返回简单的信息。学习了fs模块,可以利用它实现更复杂的功能。

    现在有这样一个需求,在地址栏里输入网址,需要服务器返回相应的html页面,以及页面里依赖的css、js、json等格式的文件。这里的重点是根据不同的路径用fs模块读取相应的文件返回给浏览器,并且根据文件类型设置不同的 ContentType。

    准备一个mime.json文件,里面存储了后缀名和ContentType的映射关系,再创建一个getMime方法,用来返回后缀对应的ContentType

    // 包装成Promise用来实现同步方法
    function getMime(extname) {
        return new Promise((resolve, reject) => {
            fs.readFile('./data/mime.json', (err, data) => {
                if (err) {
                    reject(err)
                    return
                }
                let mimeObj = JSON.parse(data.toString())
                resolve(mimeObj[extname])
            })
        })
    }

    接着在app.js里处理请求,借用了path模块的extname方法获取后缀

    const http = require('http')
    const fs = require('fs')
    const getMime = require('./module/common.js')
    const path = require('path')
    
    const server = http.createServer((req, res) => {
        const url = new URL(req.url, 'http://127.0.0.1:3000')
        // 获取路径
        let pathname = url.pathname
        // 获取后缀
        let extname = path.extname(pathname)
        // 过滤掉图标
        if (pathname != 'favicon.ico') {
            // 默认跳转到index.html
            pathname = pathname ? pathname : 'index.html'
            fs.readFile('./static' + pathname, async (err, data) => {
                if (err) {
                    // 页面不存在返回404
                    res.setHeader('ContentType', 'text/html')
                    res.end('404')
                    return
                }
                res.statusCode = 200;
                // getMime方法——通过后缀获取对应的ContentType
                res.setHeader('ContentType', await getMime(extname))
                res.end(data)
            })
        }
    })
    
    server.listen(3000, () => {
        console.log('服务器运行在 http://localhost:3000')
    })

    目录结构:

     当我们访问 http://localhost:3000 时,默认请求index.html,浏览器解析index.html时遇到<script>、<link>标签则继续向服务器请求js、css文件,服务器根据后缀名设置不同的 ContentType 并返回相应数据。

    接下来我们把上面的处理逻辑抽离出来封装成一个方法放在新建的 routes.js 文件里:

    // 改成同步方式
    function getMime(extname) {
        let data = fs.readFileSync('./data/mime.json')
        let mimeObj = JSON.parse(data.toString())
        console.log(mimeObj[extname])
        return mimeObj[extname]
    }
    
    exports.static = function (req, res, staticPath) {
        const url = new URL(req.url, 'http://127.0.0.1:3000')
        // 获取路径
        let pathname = url.pathname
        // 过滤掉图标
        if (pathname != 'favicon.ico') {
            // 默认跳转到index.html
            pathname = pathname === '/' ? '/index.html' : pathname
            // 获取后缀
            let extname = path.extname(pathname)
            try {
                let data = fs.readFileSync('./' + staticPath + pathname)
                if (err) {
                    // 页面不存在返回404
                    res.setHeader('ContentType', 'text/html')
                    res.end('404')
                    return
                }
                res.statusCode = 200;
                // getMime方法——通过后缀获取对应的ContentType
                res.setHeader('ContentType', await getMime(extname))
                res.end(data)
     } catch (error) { } } }

    然后在app.js引入 static 方法

    const http = require('http')
    const routes = require('./module/routes')
    
    const server = http.createServer((req, res) => {
        // 如果是访问静态资源,指向static目录下的文件
        routes.static(req, res, 'static')
    })
    
    server.listen(3000, () => {
        console.log('服务器运行在 http://localhost:3000')
    })

    这样,所有请求都会先由 static 方法 处理。在实际应用中,有些资源是保存在服务器上不会变化的,称为静态资源,在本例中指的是index.html,css、js、图片等文件。通过这样一个静态web服务器我们就能够处理静态资源了。

    还有一些根据请求可以动态改变文件内容的称为动态资源,借助模板引擎可以将静态模板与动态数据结合起来生成动态文件,我们下节再讨论。

  • 相关阅读:
    PSR
    php类与对象
    二进制、位运算及其用处
    安装LNMP笔记
    计算机基础
    Python3编写HFS(CVE2014-6287)检测脚本
    windows和iis对应版本关系
    phpStudy8.1.0.1配置子域名多网站
    Xml外部实体注入
    xss小游戏通关-全答案
  • 原文地址:https://www.cnblogs.com/zdd2017/p/14658233.html
Copyright © 2011-2022 走看看