Nodejs原生实现搭建静态资源web服务器

一、编写服务程序

const http = require('http'); 
const fs = require('fs'); 
const path = require('path');
const url = require('url');
const zlib = require('zlib'); // gzip压缩模块
const mime = require('mime-types'); // 需npm安装

/**
 * 静态服务器
 * @param {String} options.hostname 主机
 * @param {Number} options.port 端口
 * @param {String} options.root 静态资源目录
 * @param {String} options.index 入口页面
 * @param {Boolean} options.gzip 是否开启gzip压缩
 * @param {String} options.compress 指定压缩的文件格式(多个格式中间以|分隔)
 * @param {Boolean} options.openBrowser 自动打开默认浏览器
 */
function staticServer(options) {
    const defaults = {
        hostname: 'localhost',
        port: 80,
        root: '../dist',
        index: 'index.html',
        gzip: true,
        compress: 'html|css|js',
        openBrowser: false
    };
    
    const settings = Object.assign({}, defaults, options); // 合并配置
    
    const rootPath = path.join(__dirname, settings.root); // 获取静态根目录路径

    //创建服务程序
    const server = http.createServer((request, response) => {
    
        let pathname = url.parse(request.url).pathname; //获得请求url路径
        const filePath = path.join(rootPath, pathname.slice(-1) === '/' ? settings.index : pathname); // 如果url是/,默认加载index页面

        // 检测文件是否存在
        if (fs.existsSync(filePath)) {
            try {
                const mimeType = mime.lookup(filePath); //读取文件mime类型
                response.setHeader("Content-Type", mimeType || 'text/plain');  

                const raw = fs.createReadStream(filePath); // 以流的形式读取文件
                const ext = path.extname(filePath).slice(1); // 获得文件扩展名
                const acceptEncoding = request.headers['accept-encoding'];
                const gzipExt = settings.gzip && settings.compress.includes(ext); // 开启了gzip压缩,且文件类型在压缩格式范围内

                if (gzipExt && acceptEncoding.includes('gzip')) {
                    response.writeHead(200, "Ok", { 'Content-Encoding': 'gzip' });
                    raw.pipe(zlib.createGzip()).pipe(response);
                } else if (gzipExt && acceptEncoding.includes('deflate')) {
                    response.writeHead(200, "Ok", { 'Content-Encoding': 'deflate' });
                    raw.pipe(zlib.createDeflate()).pipe(response);
                } else {
                    response.writeHead(200, "Ok");
                    raw.pipe(response);
                }

            } catch (err) {
                response.writeHead(500, { 'Content-Type': 'text/plain' });
                response.end(err);
            }
        } else {
            //如果文件不存在返回404
            response.writeHead(404, { 'Content-Type': 'text/plain' });
            response.write("This request URL " + pathname + " was not found on this server.");
            response.end();
        }

    });
    
    // 打开默认浏览器
    const openDefaultBrowser = (url) => {
        const { exec } = require('child_process');
        console.log(process.platform)
        switch (process.platform) {
            case "darwin":
                exec('open ' + url);
                break;
            case "win32":
                exec('start ' + url);
                break;
            default:
                exec('xdg-open', [url]);
        }
    }

    //监听主机端口
    const { hostname, port, openBrowser } = settings;
    server.listen(port, hostname, () => {
        const url = `http://${hostname}:${port}`
        console.log(`服务器运行在 ${url}`);
        openBrowser && openDefaultBrowser(url); // 打开默认浏览器
    });
}


// 启动静态服务器
staticServer({ 
    hostname: '127.0.0.1',  //主机
    port: 3000, // 端口
    root: './dist', // 静态文件目录
    index: 'index.html', // 入口文件
    gzip: true, // 开启gzip压缩
    compress: 'html|css|js', // 压缩这三种格式
    openBrowser: true  // 服务启动后自动打开浏览器
});

二、运行服务程序

node .server.js

参考资料:https://blog.csdn.net/qq_30422457/article/details/82497468

上一篇:基于nodejs手机网页端购物电商系统.rar(含源码)


下一篇:nodejs 使用puppeteer模块在nodejs中模拟浏览器运行,载入脚本,输出结果