搭建Node.js服务器

1.基础HTTP服务器:
  • 添加了路由处理
  • 添加了404错误处理
  • 添加了服务器错误监听
2.静态资源服务器:
  • 使用异步文件操作
  • 支持目录自动索引(默认加载 index.html)
  • 自动检测文件类型并设置正确Content-Type
  • 更完善的错误处理
3.处理GET请求参数
  • 提供了一个HTML表单用于测试
  • 使用url模块解析URL和查询参数
  • 清晰展示接收到的GET参数
4.处理POST请求参数:
  • 提供了一个HTML表单用于测试
  • 使用流的方式处理POST数据
  • 正确解析表单数据
  • 清晰展示接收到的POST参数

一、HTTP模块

html 复制代码
const http = require("http");

// 创建服务器实例
const app = http.createServer((req, res) => {
    // 设置响应头,指定内容类型和编码
    res.setHeader("Content-Type", "text/html;charset=utf-8");
    
    // 根据请求路径返回不同内容
    switch (req.url) {
        case "/":
            res.end("欢迎访问主页!");
            break;
        case "/about":
            res.end("这是关于页面!");
            break;
        default:
            res.statusCode = 404;
            res.end("404 - 页面未找到");
    }
});

// 监听端口并启动服务器
app.listen(5000, () => {
    console.log("服务器已启动!监听在 http://localhost:5000");
});

// 添加错误处理
app.on("error", (error) => {
    console.error(`服务器启动失败: ${error.message}`);
});    

二、静态资源服务器

html 复制代码
const http = require("http");
const fs = require("fs").promises;
const path = require("path");

// 定义静态资源目录
const STATIC_DIR = path.join(__dirname, "static");

// 内容类型映射表
const CONTENT_TYPES = {
    ".html": "text/html",
    ".css": "text/css",
    ".js": "text/javascript",
    ".json": "application/json",
    ".png": "image/png",
    ".jpg": "image/jpeg",
    ".gif": "image/gif",
    ".svg": "image/svg+xml",
    ".txt": "text/plain"
};

const app = http.createServer(async (req, res) => {
    try {
        // 构建文件路径
        let filePath = path.join(STATIC_DIR, req.url === "/" ? "index.html" : req.url);
        
        // 检查文件是否存在
        await fs.access(filePath);
        
        // 获取文件状态
        const stat = await fs.stat(filePath);
        
        if (stat.isDirectory()) {
            // 如果是目录,尝试默认文件
            filePath = path.join(filePath, "index.html");
            await fs.access(filePath);
        }
        
        // 获取文件扩展名并确定内容类型
        const extname = path.extname(filePath);
        const contentType = CONTENT_TYPES[extname] || "application/octet-stream";
        
        // 设置响应头并发送文件内容
        res.setHeader("Content-Type", contentType);
        const fileContent = await fs.readFile(filePath);
        res.end(fileContent);
    } catch (error) {
        // 处理错误
        res.statusCode = 404;
        res.end("404 - 文件未找到");
    }
});

app.listen(3000, () => {
    console.log("服务器监听在 http://localhost:3000");
});    

三、服务器获取get请求参数

在./static下面写一个index.html页面,页面中发送一个get请求

html 复制代码
const http = require("http");
const url = require("url");
const qs = require("querystring");

const app = http.createServer((req, res) => {
    res.setHeader("Content-Type", "text/html;charset=utf-8");
    
    // 解析URL和查询参数
    const parsedUrl = url.parse(req.url, true);
    const pathname = parsedUrl.pathname;
    const query = parsedUrl.query;
    
    if (pathname === "/") {
        // 返回表单页面
        const formHtml = `
            <form method="GET" action="/api">
                <input type="text" name="username" placeholder="用户名">
                <input type="password" name="password" placeholder="密码">
                <button type="submit">提交</button>
            </form>
        `;
        res.end(formHtml);
    } else if (pathname === "/api") {
        // 处理GET请求参数
        res.end(`收到GET请求,参数:${JSON.stringify(query)}`);
    } else {
        res.statusCode = 404;
        res.end("404 - 页面未找到");
    }
});

app.listen(8888, () => {
    console.log("服务器已启动!地址为: http://localhost:8888");
});    

四、服务器获取post请求参数

获取post请求的参数,通过给req绑定事件和end事件,来获取监听的参数,data事件一个接收的事件,end事件 当post请求的参数都接收完毕,就出发end事件

html 复制代码
const http = require("http");
const qs = require("querystring");

const app = http.createServer((req, res) => {
    res.setHeader("Content-Type", "text/html;charset=utf-8");
    
    if (req.url === "/") {
        // 返回表单页面
        const formHtml = `
            <form method="POST" action="/api">
                <input type="text" name="username" placeholder="用户名">
                <input type="password" name="password" placeholder="密码">
                <button type="submit">提交</button>
            </form>
        `;
        res.end(formHtml);
    } else if (req.url === "/api" && req.method === "POST") {
        // 处理POST请求
        let body = "";
        
        // 监听data事件,收集数据块
        req.on("data", (chunk) => {
            body += chunk.toString();
        });
        
        // 监听end事件,数据接收完成
        req.on("end", () => {
            // 解析表单数据
            const formData = qs.parse(body);
            
            // 返回处理结果
            res.end(`收到POST请求,参数:${JSON.stringify(formData)}`);
        });
    } else {
        res.statusCode = 404;
        res.end("404 - 页面未找到");
    }
});

app.listen(8888, () => {
    console.log("服务器已启动!地址为: http://localhost:8888");
});    

每个步骤的代码都可以独立运行,并且包含了必要的注释以便理解

相关推荐
海宇AI3 小时前
零信任架构实战:基于海宇个人风险报告构建自动化分期商城信用额度初审网关
运维·人工智能·架构·自动化
IMPYLH3 小时前
Linux 的时间为什么会被拨回去
linux·运维·服务器
2601_963282774 小时前
寒地窄带通信工程实践:黑龙江哈尔滨对讲机选型、组网与合规运维总结
运维·服务器·网络
叼烟扛炮5 小时前
[Git 实战] 学习笔记:从生成 SSH 密钥到解决 TortoiseGit 推送报错全指南
linux·运维·笔记·git·学习
xbzb5 小时前
OpenStack 网络管理(理论):Linux 网络虚拟化是 Neutron 的地基
linux·服务器·网络·openstack·network·neutron
我要见SA姐16 小时前
GitHub Actions 自动化:5 个真实运维提效案例
运维·数据库·机器学习·oracle·回归
Android系统攻城狮6 小时前
Linux FFmpeg深度解析之avcodec_flush_buffers调用流程与实战(十九)
linux·运维·服务器·ffmpeg·车载音视频·ffmpeg音视频进阶
Y3815326628 小时前
用 httpx 写 SerpBase 异步客户端:连接池与超时配置
运维·服务器·数据库
倔强的石头1068 小时前
【Linux指南】进程通信系列(七):System V 信号量 —— 同步互斥的内核原语
linux·运维·服务器
Hone9 小时前
我把「自动发文章到掘金」做成了一个 Agent 技能:juejin-skills
node.js·ai编程·前端工程化