文章目录

  • 一、HTTP模块入门:从零搭建第一个服务器
    • 1.1 基础概念解析
    • 1.2 手把手创建服务器
  • 二、核心功能深入解析
    • 2.1 处理不同请求类型
    • 2.2 实现文件下载功能
  • 三、常见问题解决方案
    • 3.1 跨域问题处理
    • 3.2 防止服务崩溃
    • 3.3 调试技巧
  • 四、安全最佳实践
    • 4.1 请求头安全设置
    • 4.2 速率限制(防止DDoS攻击)
  • 五、简易版博客系统
    • 5.1 项目结构
    • 5.2 环境准备
    • 5.3 核心代码实现

一、HTTP模块入门:从零搭建第一个服务器

1.1 基础概念解析

HTTP 模块是什么?
Node.js内置的 http 模块提供了创建 HTTP 服务器和客户端的能力。就像快递公司:

  • 服务器:像仓库,存储货物(数据)
  • 客户端:像快递员,负责收发货物(请求和响应)

核心对象解释:

  • http.createServer:创建服务器
  • req对象:包含客户端请求的信息(地址、请求头等)
  • res对象:用来给客户端发送响应

1.2 手把手创建服务器

// 导入模块(类似取快递工具)
const http = require('http');// 创建服务器(建立仓库)
const server = http.createServer((req, res) => {// 设置响应头(告诉快递员包裹类型)res.writeHead(200, { 'Content-Type': 'text/html; charset=utf-8' }); // 明确指定编码,不然运行之后是乱码// 发送响应内容(实际运送的货物)res.end('<h1>欢迎来到我的网站!</h1>');
})// 启动监听(设置仓库门牌号)
server.listen(3000, () => {console.log('服务器已在 http://localhost:3000 启动')
})

二、核心功能深入解析

2.1 处理不同请求类型

GET 请求参数获取

const { URL } = require('url');server.on('request', (req, res) => {// 解析URL(类似拆包裹看地址标签)const urlObj = new URL(req.url, `http://${req.headers.host}`);// 获取查询参数(比如?name=John)console.log(urlObj.searchParams.get('name')); // 输出 John
})

POST 请求数据处理

let body = [];
req.on('data', chunk => {body.push(chunk); //接收数据块(像接收多个包裹)
}).on('end', () => {body = Buffer.concat(body).toString(); // 合并所有数据块console.log('收到POST数据:', body);
})

2.2 实现文件下载功能

const fs = require('fs');function downloadFile(res, filePath) {// 设置响应头(高速浏览器这是要下载的文件)res.writeHead(200, {'Content-Type': 'application/octet-stream','Content-Disposition': `attachment; filename=${path.basename(filePath)}`});// 创建文件流(像打开水龙头放水)const fileStream = fs.createReadStream(filePath);fileStream.pipe(res); // 将文件流导向响应
}

三、常见问题解决方案

3.1 跨域问题处理

// 在响应头中添加CORS支持
res.setHeader('Access-Control-Allow-Origin', '*');
res.setHeader('Access-Control-Allow-Methods', 'GET, POST, OPTIONS');
res.setHeader('Access-Control-Allow-Headers', 'Content-Type');

3.2 防止服务崩溃

// 全局错误捕获
process.on('uncaughtException', (err) => {console.error('全局异常捕获:', err);// 可以记录日志或发送警报
});// 处理Promise拒绝
process.on('unhandledRejection', (reason, promise) => {console.error('未处理的Promise拒绝:', reason);
});

3.3 调试技巧

使用 curl 测试接口:

# 测试GET请求
curl http://localhost:3000/api/data# 测试POST请求
curl -X POST -d "username=john" http://localhost:3000/login

四、安全最佳实践

4.1 请求头安全设置

res.setHeader('X-Content-Type-Options', 'nosniff');
res.setHeader('X-Frame-Options', 'DENY');
res.setHeader('Content-Security-Policy', "default-src 'self'");

4.2 速率限制(防止DDoS攻击)

const rateLimit = require('express-rate-limit');const limiter = rateLimit({windowMs: 15 * 60 * 1000, // 15分钟max: 100 // 每个IP最多100次请求
});// 应用中间件
server.use(limiter);

五、简易版博客系统

5.1 项目结构

/my-blog
├── data/            # 数据存储
│   └── articles.json
├── public/          # 静态资源
│   ├── css/
│   └── js/
│   └── index.html
├── controllers/     # 业务逻辑
│   └── articleController.js
├── routes/          # 路由配置
│   └── articleRoutes.js
├── utils/           # 工具函数
│   └── fileUtils.js
└── server.js        # 入口文件

5.2 环境准备

1.初始化项目

mkdir my-blog && cd my-blog
npm init -y

2.安装依赖

npm install uuid      # 生成唯一ID

5.3 核心代码实现

1.数据存储(data/articles.json)

{"articles": [{"id": "1","title": "Node.js入门指南","content": "Node.js是一个基于Chrome V8引擎的JavaScript运行环境...","createdAt": "2023-08-20"}]
}

2.工具函数(utils/fileUtils.js)

const fs = require('fs').promises;
const path = require('path');const dataPath = path.join(__dirname, '../data/articles.json');async function readData() {try {const data = await fs.readFile(dataPath, 'utf8');return JSON.parse(data);} catch (err) {return { articles: [] };}
}async function writeData(data) {await fs.writeFile(dataPath, JSON.stringify(data, null, 2));
}module.exports = { readData, writeData };

3. 控制器(controllers/articleController.js)

const { v4: uuidv4 } = require('uuid');
const { readData, writeData } = require('../utils/fileUtils');// 获取所有文章
async function getAllArticles() {const data = await readData();return data.articles;
}// 创建新文章
async function createArticle(title, content) {const data = await readData();const newArticle = {id: uuidv4(),title,content,createdAt: new Date().toISOString().split('T')[0]};data.articles.push(newArticle);await writeData(data);return newArticle;
}// 删除文章
async function deleteArticle(id) {const data = await readData();data.articles = data.articles.filter(article => article.id !== id);await writeData(data);
}module.exports = { getAllArticles, createArticle, deleteArticle };

4. 路由配置(routes/articleRoutes.js)

const http = require('http');
const fs = require('fs');
const path = require('path');// 假设这是文章数据存储
let articles = [];
let nextId = 1;function handleRoutes(req, res) {const urlParts = req.url.split('/');if (req.url === '/api/articles' && req.method === 'GET') {res.writeHead(200, { 'Content-Type': 'application/json' });res.end(JSON.stringify(articles));} else if (req.url === '/api/articles' && req.method === 'POST') {let body = '';req.on('data', chunk => {body += chunk.toString();});req.on('end', () => {const newArticle = JSON.parse(body);newArticle.id = nextId++;articles.push(newArticle);res.writeHead(201, { 'Content-Type': 'application/json' });res.end(JSON.stringify(newArticle));});} else if (urlParts[1] === 'api' && urlParts[2] === 'articles' && req.method === 'DELETE') {if (urlParts.length === 3) {// 批量删除articles = [];res.writeHead(200, { 'Content-Type': 'application/json' });res.end(JSON.stringify({ message: '所有文章删除成功' }));} else {// 单篇删除const id = parseInt(urlParts[3]);const index = articles.findIndex(article => article.id === id);if (index !== -1) {articles.splice(index, 1);res.writeHead(200, { 'Content-Type': 'application/json' });res.end(JSON.stringify({ message: '文章删除成功' }));} else {res.writeHead(404, { 'Content-Type': 'application/json' });res.end(JSON.stringify({ message: '文章未找到' }));}}} else {res.writeHead(404, { 'Content-Type': 'text/plain' });res.end('Not Found');}
}module.exports = handleRoutes;

5. 主服务器(server.js)

const http = require('http');
const fs = require('fs');
const path = require('path');
const handleRoutes = require('./routes/articleRoutes');// 创建HTTP服务器
const server = http.createServer(async (req, res) => {// 静态文件服务if (req.url.startsWith('/public/')) {const filePath = path.join(__dirname, req.url);fs.readFile(filePath, (err, data) => {if (err) {res.writeHead(404);return res.end('File not found');}res.writeHead(200);res.end(data);});return;}// API路由处理handleRoutes(req, res);
});// 启动服务器
const PORT = 3000;
server.listen(PORT, () => {console.log(`Server running at http://localhost:${PORT}`);
});

6.页面样式跟逻辑

// public/js/app.js
// 加载文章列表的函数
async function loadArticles() {try {const response = await fetch('/api/articles');if (!response.ok) {throw new Error('网络响应失败');}const articles = await response.json();const articlesDiv = document.getElementById('articles');articlesDiv.innerHTML = '';articles.forEach(article => {const articleElement = document.createElement('div');articleElement.innerHTML = `<h2>${article.title}</h2><p>${article.content}</p><button onclick="deleteArticle('${article.id}')">删除文章</button>`;articlesDiv.appendChild(articleElement);});} catch (error) {console.error('加载文章列表时出错:', error);}
}// 删除文章的函数
async function deleteArticle(id) {try {const response = await fetch(`/api/articles/${id}`, {method: 'DELETE'});if (!response.ok) {throw new Error('删除文章失败');}// 重新加载文章列表loadArticles();} catch (error) {console.error('删除文章时出错:', error);}
}// 添加文章的函数
async function addArticle(event) {event.preventDefault();const title = document.getElementById('title').value;const content = document.getElementById('content').value;try {const response = await fetch('/api/articles', {method: 'POST',headers: {'Content-Type': 'application/json'},body: JSON.stringify({ title, content })});if (!response.ok) {throw new Error('添加文章失败');}// 清空表单document.getElementById('articleForm').reset();// 重新加载文章列表loadArticles();} catch (error) {console.error('添加文章时出错:', error);}
}// 页面加载完成后自动加载文章列表
window.addEventListener('DOMContentLoaded', loadArticles);
// public/index.html
<!DOCTYPE html>
<html>
<head><!-- 添加字符编码声明 --><meta charset="UTF-8"><title>我的博客</title><link rel="stylesheet" href="/public/css/style.css">
</head>
<body><div id="app"><h1>文章列表</h1><!-- 修改文章表单,移除文件输入框 --><form id="articleForm" onsubmit="addArticle(event)"><input type="text" id="title" placeholder="文章标题" required><textarea id="content" placeholder="文章内容" required></textarea><button type="submit">添加文章</button></form><div id="articles"></div><button onclick="loadArticles()">刷新列表</button></div><script src="/public/js/app.js"></script>
</body>
</html>
// public/css/style.css
body {font-family: Arial, sans-serif;line-height: 1.6;margin: 0;padding: 0;background-color: #f4f4f4;
}#app {width: 80%;margin: auto;overflow: hidden;padding: 20px;
}h1 {color: #333;text-align: center;
}#articleForm {background-color: #fff;padding: 20px;margin-bottom: 20px;border-radius: 5px;box-shadow: 0 0 5px rgba(0, 0, 0, 0.1);
}#articleForm input[type="text"],
#articleForm textarea {width: 100%;padding: 10px;margin-bottom: 10px;border: 1px solid #ddd;border-radius: 3px;
}#articleForm button {background-color: #333;color: #fff;padding: 10px 20px;border: none;border-radius: 3px;cursor: pointer;
}#articleForm button:hover {background-color: #555;
}#articles div {background-color: #fff;padding: 20px;margin-bottom: 10px;border-radius: 5px;box-shadow: 0 0 5px rgba(0, 0, 0, 0.1);
}#articles h2 {margin-top: 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/pingmian/82573.shtml
繁体地址,请注明出处:http://hk.pswp.cn/pingmian/82573.shtml
英文地址,请注明出处:http://en.pswp.cn/pingmian/82573.shtml

如若内容造成侵权/违法违规/事实不符,请联系英文站点网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

SSM整合:Spring+SpringMVC+MyBatis完美融合实战指南

前言 在Java企业级开发领域&#xff0c;SSM&#xff08;SpringSpringMVCMyBatis&#xff09;框架组合一直占据着重要地位。这三个轻量级框架各司其职又相互配合&#xff0c;为开发者提供了高效、灵活的开发体验。本文将深入探讨SSM框架的整合过程&#xff0c;揭示整合背后的原…

[AI]大模型MCP快速入门及智能体执行模式介绍

[AI]大模型MCP快速入门及智能体执行模式介绍 一、MCP入门 介绍 MCP&#xff08;Model Context Protocol&#xff0c;模型上下文协议&#xff09;是一种由Anthropic公司于2024年提出的开放标准协议&#xff0c;旨在为大型语言模型&#xff08;LLM&#xff09;提供统一接口&am…

Mac M1 安装 ffmpeg

1.前言 官网那货没有准备m系列的静态包&#xff0c;然后我呢&#xff0c;不知道怎么想的就从maven项目中的 javacv-platform&#xff0c;且版本为1.5.11依赖里面将这个静态包把了出来&#xff0c;亲测能用&#xff0c;感觉比那些网上说的用什么wget编译安装、brew安装快多了。…

unity控制相机围绕物体旋转移动

记录一下控制相机围绕物体旋转与移动的脚本&#xff0c;相机操作思路分为两块&#xff0c;一部分为旋转&#xff0c;一部分为移动&#xff0c;旋转是根据当前center中心点的坐标&#xff0c;根据距离设置与默认的旋转进行位置移动&#xff0c;移动是根据相机的左右和前后进行计…

python打卡day38@浙大疏锦行

知识点回顾&#xff1a; Dataset类的__getitem__和__len__方法&#xff08;本质是python的特殊方法&#xff09;Dataloader类minist手写数据集的了解 作业&#xff1a;了解下cifar数据集&#xff0c;尝试获取其中一张图片 一、首先加载CIFAR数据集 import torch import torchvi…

用户配置文件(Profile)

2.4.5 用户配置文件&#xff08;Profile&#xff09; 用户配置文件由以下组件构成&#xff1a; 一个运营商安全域&#xff08;MNO-SD&#xff09; 辅助安全域&#xff08;SSD&#xff09;和CASD Applets 应用程序&#xff08;如NFC应用&#xff09; 网络接入应用&#xff…

如何给自研MCP加上安全验证

前言 刚过去两个月,市面的 MCP 服务,如雨后春笋一般不断涌现出来,包括;百度、高德、网盘、支付宝。这些 MCP 服务,可以让我们基于 Spring AI 框架构建的 Agent 具备非常丰富的使用功能。同时这也说明,程序员👨🏻‍💻,应该具备开发 MCP 服务的能力,Spring AI 让 J…

Unity网络开发实践项目

摘要&#xff1a;该网络通信系统基于Unity实现&#xff0c;包含以下几个核心模块&#xff1a; 协议配置&#xff1a;通过XML定义枚举&#xff08;如玩家/英雄类型&#xff09;、数据结构&#xff08;如PlayerData&#xff09;及消息协议&#xff08;如PlayerMsg&#xff09;&a…

OpenCV CUDA模块图像过滤------创建一个 Sobel 滤波器函数createSobelFilter()

操作系统&#xff1a;ubuntu22.04 OpenCV版本&#xff1a;OpenCV4.9 IDE:Visual Studio Code 编程语言&#xff1a;C11 算法描述 该函数用于创建一个 Sobel 滤波器&#xff0c;用于在 GPU 上进行边缘检测。它基于图像的梯度计算&#xff1a; dx 表示对 x 方向求导的阶数&…

【JavaSE】枚举和注解学习笔记

枚举和注解 -枚举 规定多选一数据类型的解决方案-枚举 枚举对应英文(enumeration,简写 enum) 2)枚举是一组常量的集合。 3)可以这里理解:枚举属于一种特殊的类&#xff0c;里面只包含一组有限的特定的对象。 枚举的两种实现方式 自定义实现枚举 使用enum关键字实现枚举 自…

Spark SQL进阶:解锁大数据处理的新姿势

目录 一、Spark SQL&#xff0c;为何进阶&#xff1f; 二、进阶特性深剖析 2.1 窗口函数&#xff1a;数据洞察的新视角 2.2 高级聚合&#xff1a;挖掘数据深度价值 2.3 自定义函数&#xff08;UDF 和 UDTF&#xff09;&#xff1a;拓展功能边界 三、性能优化实战 3.1 数…

如何利用 Conda 安装 Pytorch 教程 ?

如何利用 Conda 安装 Pytorch 教程 &#xff1f; 总共分为六步走&#xff1a; &#xff08;1&#xff09;第一步&#xff1a;验证conda 环境是否安装好&#xff1f; 1) conda -V2) conda --version&#xff08;2&#xff09;第二步&#xff1a;查看现有环境 conda env list…

什么是HTTP

HTTP&#xff08;HyperText Transfer Protocol&#xff09;是万维网数据通信的基础协议&#xff0c;作为应用层协议具有以下关键特性&#xff1a; 客户端-服务器模型&#xff1a;基于请求/响应模式 无状态协议&#xff1a;默认不保留通信状态 可扩展性&#xff1a;通过首部字…

2025-05-27 学习记录--Python-模块

合抱之木&#xff0c;生于毫末&#xff1b;九层之台&#xff0c;起于累土&#xff1b;千里之行&#xff0c;始于足下。&#x1f4aa;&#x1f3fb; 一、模块 ⭐️ &#xff08;一&#xff09;模块的导入与使用 &#x1f36d; 模块的导入&#xff1a;&#x1f41d; 模块 就好比…

leetcode 131. Palindrome Partitioning

目录 一、题目描述 二、方法1、回溯法每次暴力判断回文子串 三、方法2、动态规划回溯法 一、题目描述 分割回文子串 131. Palindrome Partitioning 二、方法1、回溯法每次暴力判断回文子串 class Solution {vector<vector<string>> res;vector<string>…

重构开发范式!飞算JavaAI革新Spring Cloud分布式系统开发

分布式系统凭借高可用性、可扩展性等核心优势&#xff0c;成为大型软件项目的标配架构。Spring Cloud作为Java生态最主流的分布式开发框架&#xff0c;虽被广泛应用于微服务架构搭建&#xff0c;但其传统开发模式却面临效率瓶颈——从服务注册中心配置到网关路由规则编写&#…

python 生成复杂表格,自动分页等功能

py&#xff54;&#xff48;&#xff4f;&#xff4e; 生成复杂表格&#xff0c;自动分页等功能 解决将Python中的树形目录数据转换为Word表格&#xff0c;并生成带有合并单元格的检测报告的问题。首先&#xff0c;要解决“tree目录数据”和“Word表格互换”&#xff0c;指将树…

根据Cortex-M3(包括STM32F1)权威指南讲解MCU内存架构与如何查看编译器生成的地址具体位置

首先我们先查看官方对于Cortex-M3预定义的存储器映射 1.存储器映射 1.1 Cortex-M3架构的存储器结构 内部私有外设总线&#xff1a;即AHB总线&#xff0c;包括NVIC中断&#xff0c;ITM硬件调试&#xff0c;FPB, DWT。 外部私有外设总线&#xff1a;即APB总线&#xff0c;用于…

Linux中硬件信息查询利器——lshw命令详解!

lshw&#xff08;List Hardware&#xff09;是 Linux 系统下的一款命令行工具&#xff0c;用于全面检测并显示详细的硬件信息。它能够报告 CPU、内存、主板、存储设备、显卡、网络设备等几乎所有硬件组件的详细信息&#xff0c;适用于系统管理、故障排查和硬件兼容性检查等场景…

用llama3微调了一个WiFiGPT 用于室内定位

一段话总结 本文提出WiFiGPT,一种基于Decoder-Only Transformer(如LLaMA 3)的室内定位系统,通过将WiFi遥测数据(如CSI、FTM、RSSI)转换为文本序列进行端到端训练,无需手工特征工程即可实现高精度定位。实验表明,WiFiGPT在LOS环境中实现亚米级精度(MAE低至0.90米),在…