Skip to content

第7章:HTTP 服务器开发

7.1 http模块创建基础HTTP服务器

Node.js 的 http 模块是创建 HTTP 服务器的核心,它允许我们构建一个能够处理 HTTP 请求和响应的服务器。

基本步骤

  1. 导入 http 模块
  2. 使用 http.createServer() 创建服务器
  3. 监听指定端口

示例

javascript
const http = require('http');

// 创建 HTTP 服务器
const server = http.createServer((req, res) => {
  // 设置响应状态码和响应头
  res.writeHead(200, { 'Content-Type': 'text/plain' });
  
  // 发送响应内容
  res.end('Hello, Node.js HTTP Server!\n');
});

// 监听端口
const port = 3000;
server.listen(port, () => {
  console.log(`服务器运行在 http://localhost:${port}`);
});

运行服务器

bash
node server.js

打开浏览器访问 http://localhost:3000,你应该会看到 "Hello, Node.js HTTP Server!" 的响应。

7.2 服务器响应处理

HTTP 服务器的核心是处理请求和生成响应。在 createServer 回调函数中,我们可以通过 req(请求对象)获取请求信息,通过 res(响应对象)发送响应。

请求对象 (req)

req 对象包含了客户端发送的请求信息,常用属性和方法:

  • req.url:请求的 URL 路径
  • req.method:请求的 HTTP 方法(GET、POST 等)
  • req.headers:请求头信息
  • req.on('data', callback):监听请求体数据
  • req.on('end', callback):监听请求体数据结束

响应对象 (res)

res 对象用于向客户端发送响应,常用方法:

  • res.writeHead(statusCode, headers):设置响应状态码和响应头
  • res.write(data):发送响应体数据
  • res.end(data):结束响应并发送响应体数据

示例

javascript
const http = require('http');

const server = http.createServer((req, res) => {
  console.log('请求方法:', req.method);
  console.log('请求路径:', req.url);
  console.log('请求头:', req.headers);
  
  // 设置响应头
  res.writeHead(200, {
    'Content-Type': 'text/plain',
    'X-Powered-By': 'Node.js'
  });
  
  // 发送响应内容
  res.end(`Hello, Node.js!\n请求路径: ${req.url}\n请求方法: ${req.method}`);
});

const port = 3000;
server.listen(port, () => {
  console.log(`服务器运行在 http://localhost:${port}`);
});

7.3 HTTP请求方法

HTTP 请求方法表示客户端对服务器资源的操作类型,常用的请求方法:

  • GET:请求获取资源
  • POST:提交数据,请求服务器处理
  • PUT:更新资源
  • DELETE:删除资源
  • PATCH:部分更新资源
  • HEAD:请求资源的头部信息
  • OPTIONS:请求服务器支持的请求方法

示例:处理不同的 HTTP 请求方法

javascript
const http = require('http');

const server = http.createServer((req, res) => {
  const { url, method } = req;
  
  res.writeHead(200, { 'Content-Type': 'text/plain' });
  
  switch (method) {
    case 'GET':
      res.end(`GET 请求: ${url}`);
      break;
    case 'POST':
      res.end(`POST 请求: ${url}`);
      break;
    case 'PUT':
      res.end(`PUT 请求: ${url}`);
      break;
    case 'DELETE':
      res.end(`DELETE 请求: ${url}`);
      break;
    default:
      res.end(`未处理的请求方法: ${method}`);
  }
});

const port = 3000;
server.listen(port, () => {
  console.log(`服务器运行在 http://localhost:${port}`);
});

7.4 路由基础

路由是根据请求的 URL 路径和 HTTP 方法来决定如何处理请求的机制。在 Node.js 中,我们可以通过解析 req.url 来实现简单的路由。

示例:实现简单的路由

javascript
const http = require('http');
const url = require('url');

const server = http.createServer((req, res) => {
  const { pathname, query } = url.parse(req.url, true);
  const method = req.method;
  
  res.writeHead(200, { 'Content-Type': 'text/plain' });
  
  // 路由处理
  if (pathname === '/' && method === 'GET') {
    res.end('首页');
  } else if (pathname === '/about' && method === 'GET') {
    res.end('关于页面');
  } else if (pathname === '/contact' && method === 'GET') {
    res.end('联系页面');
  } else if (pathname === '/api/users' && method === 'GET') {
    res.writeHead(200, { 'Content-Type': 'application/json' });
    res.end(JSON.stringify({
      users: [
        { id: 1, name: '张三' },
        { id: 2, name: '李四' }
      ]
    }));
  } else {
    res.writeHead(404, { 'Content-Type': 'text/plain' });
    res.end('404 Not Found');
  }
});

const port = 3000;
server.listen(port, () => {
  console.log(`服务器运行在 http://localhost:${port}`);
});

7.5 静态资源托管

静态资源托管是指服务器提供静态文件(如 HTML、CSS、JS、图片等)的能力。在 Node.js 中,我们可以通过 fs 模块读取静态文件并发送给客户端。

示例:实现简单的静态资源托管

javascript
const http = require('http');
const fs = require('fs');
const path = require('path');
const url = require('url');

const server = http.createServer((req, res) => {
  const { pathname } = url.parse(req.url);
  
  // 静态资源目录
  const staticDir = path.join(__dirname, 'public');
  
  // 构建文件路径
  let filePath = path.join(staticDir, pathname);
  
  // 如果是目录,默认返回 index.html
  if (pathname.endsWith('/')) {
    filePath = path.join(filePath, 'index.html');
  }
  
  // 获取文件扩展名
  const extname = path.extname(filePath);
  
  // 设置内容类型
  let contentType = 'text/plain';
  switch (extname) {
    case '.html':
      contentType = 'text/html';
      break;
    case '.css':
      contentType = 'text/css';
      break;
    case '.js':
      contentType = 'text/javascript';
      break;
    case '.json':
      contentType = 'application/json';
      break;
    case '.png':
      contentType = 'image/png';
      break;
    case '.jpg':
    case '.jpeg':
      contentType = 'image/jpeg';
      break;
    case '.gif':
      contentType = 'image/gif';
      break;
  }
  
  // 读取文件
  fs.readFile(filePath, (err, data) => {
    if (err) {
      // 文件不存在
      if (err.code === 'ENOENT') {
        res.writeHead(404, { 'Content-Type': 'text/plain' });
        res.end('404 Not Found');
      } else {
        // 其他错误
        res.writeHead(500, { 'Content-Type': 'text/plain' });
        res.end('500 Internal Server Error');
      }
      return;
    }
    
    // 发送文件
    res.writeHead(200, { 'Content-Type': contentType });
    res.end(data);
  });
});

const port = 3000;
server.listen(port, () => {
  console.log(`服务器运行在 http://localhost:${port}`);
});

创建静态资源目录

bash
mkdir -p public

创建 index.html 文件

html
<!DOCTYPE html>
<html lang="zh-CN">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>静态网站</title>
  <link rel="stylesheet" href="style.css">
</head>
<body>
  <h1>Hello, Node.js 静态网站!</h1>
  <p>这是一个由 Node.js 服务器托管的静态网站。</p>
  <script src="script.js"></script>
</body>
</html>

创建 style.css 文件

css
body {
  font-family: Arial, sans-serif;
  margin: 0;
  padding: 20px;
  background-color: #f0f0f0;
}

h1 {
  color: #333;
}

p {
  color: #666;
}

创建 script.js 文件

javascript
console.log('Hello, Node.js!');
document.querySelector('p').textContent = '这是由 JavaScript 动态修改的内容!';

7.6 实操案例:创建一个简单的静态网站服务器

步骤1:创建项目结构

bash
mkdir -p nodejs-static-server/public
cd nodejs-static-server

步骤2:创建 server.js 文件

javascript
// server.js
const http = require('http');
const fs = require('fs');
const path = require('path');
const url = require('url');

const server = http.createServer((req, res) => {
  const { pathname } = url.parse(req.url);
  
  // 静态资源目录
  const staticDir = path.join(__dirname, 'public');
  
  // 构建文件路径
  let filePath = path.join(staticDir, pathname);
  
  // 如果是目录,默认返回 index.html
  if (pathname.endsWith('/')) {
    filePath = path.join(filePath, 'index.html');
  }
  
  // 获取文件扩展名
  const extname = path.extname(filePath);
  
  // 设置内容类型
  let contentType = 'text/plain';
  switch (extname) {
    case '.html':
      contentType = 'text/html';
      break;
    case '.css':
      contentType = 'text/css';
      break;
    case '.js':
      contentType = 'text/javascript';
      break;
    case '.json':
      contentType = 'application/json';
      break;
    case '.png':
      contentType = 'image/png';
      break;
    case '.jpg':
    case '.jpeg':
      contentType = 'image/jpeg';
      break;
    case '.gif':
      contentType = 'image/gif';
      break;
  }
  
  // 读取文件
  fs.readFile(filePath, (err, data) => {
    if (err) {
      // 文件不存在
      if (err.code === 'ENOENT') {
        res.writeHead(404, { 'Content-Type': 'text/plain' });
        res.end('404 Not Found');
      } else {
        // 其他错误
        res.writeHead(500, { 'Content-Type': 'text/plain' });
        res.end('500 Internal Server Error');
      }
      return;
    }
    
    // 发送文件
    res.writeHead(200, { 'Content-Type': contentType });
    res.end(data);
  });
});

const port = 3000;
server.listen(port, () => {
  console.log(`服务器运行在 http://localhost:${port}`);
});

步骤3:创建静态资源文件

public 目录中创建以下文件:

index.html

html
<!DOCTYPE html>
<html lang="zh-CN">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Node.js 静态网站</title>
  <link rel="stylesheet" href="style.css">
</head>
<body>
  <header>
    <h1>Node.js 静态网站</h1>
    <nav>
      <ul>
        <li><a href="/">首页</a></li>
        <li><a href="/about.html">关于</a></li>
        <li><a href="/contact.html">联系</a></li>
      </ul>
    </nav>
  </header>
  <main>
    <section>
      <h2>欢迎来到 Node.js 静态网站</h2>
      <p>这是一个使用 Node.js 构建的静态网站服务器。</p>
      <p>你可以在这个网站中浏览不同的页面,查看静态资源的加载情况。</p>
    </section>
  </main>
  <footer>
    <p>&copy; 2026 Node.js 静态网站</p>
  </footer>
  <script src="script.js"></script>
</body>
</html>

about.html

html
<!DOCTYPE html>
<html lang="zh-CN">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>关于 - Node.js 静态网站</title>
  <link rel="stylesheet" href="style.css">
</head>
<body>
  <header>
    <h1>Node.js 静态网站</h1>
    <nav>
      <ul>
        <li><a href="/">首页</a></li>
        <li><a href="/about.html">关于</a></li>
        <li><a href="/contact.html">联系</a></li>
      </ul>
    </nav>
  </header>
  <main>
    <section>
      <h2>关于我们</h2>
      <p>我们是一个使用 Node.js 构建的静态网站示例。</p>
      <p>本网站展示了如何使用 Node.js 的 http 模块创建一个简单的静态网站服务器。</p>
    </section>
  </main>
  <footer>
    <p>&copy; 2026 Node.js 静态网站</p>
  </footer>
  <script src="script.js"></script>
</body>
</html>

contact.html

html
<!DOCTYPE html>
<html lang="zh-CN">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>联系 - Node.js 静态网站</title>
  <link rel="stylesheet" href="style.css">
</head>
<body>
  <header>
    <h1>Node.js 静态网站</h1>
    <nav>
      <ul>
        <li><a href="/">首页</a></li>
        <li><a href="/about.html">关于</a></li>
        <li><a href="/contact.html">联系</a></li>
      </ul>
    </nav>
  </header>
  <main>
    <section>
      <h2>联系我们</h2>
      <p>如果你有任何问题或建议,请随时联系我们。</p>
      <p>邮箱:contact@nodejs-example.com</p>
      <p>电话:123-456-7890</p>
    </section>
  </main>
  <footer>
    <p>&copy; 2026 Node.js 静态网站</p>
  </footer>
  <script src="script.js"></script>
</body>
</html>

style.css

css
* {
  box-sizing: border-box;
  margin: 0;
  padding: 0;
}

body {
  font-family: Arial, sans-serif;
  line-height: 1.6;
  color: #333;
  background-color: #f4f4f4;
}

header {
  background-color: #333;
  color: #fff;
  padding: 20px;
  text-align: center;
}

nav ul {
  list-style: none;
  margin-top: 10px;
}

nav ul li {
  display: inline;
  margin: 0 10px;
}

nav ul li a {
  color: #fff;
  text-decoration: none;
}

nav ul li a:hover {
  text-decoration: underline;
}

main {
  padding: 20px;
  max-width: 800px;
  margin: 0 auto;
  background-color: #fff;
  min-height: 400px;
}

section {
  margin-bottom: 20px;
}

h2 {
  color: #333;
  margin-bottom: 10px;
}

p {
  margin-bottom: 10px;
}

footer {
  background-color: #333;
  color: #fff;
  text-align: center;
  padding: 10px;
  margin-top: 20px;
}

script.js

javascript
console.log('Node.js 静态网站加载成功!');

// 添加页面加载动画
window.addEventListener('load', () => {
  const main = document.querySelector('main');
  main.style.opacity = '0';
  main.style.transition = 'opacity 0.5s ease-in-out';
  
  setTimeout(() => {
    main.style.opacity = '1';
  }, 100);
});

步骤4:运行服务器

bash
node server.js

步骤5:访问网站

打开浏览器,访问以下地址:

  • 首页:http://localhost:3000
  • 关于页面:http://localhost:3000/about.html
  • 联系页面:http://localhost:3000/contact.html

小结

  • Node.js 的 http 模块是创建 HTTP 服务器的核心
  • HTTP 服务器的核心是处理请求和生成响应
  • 可以通过解析 req.url 实现简单的路由
  • 可以通过 fs 模块实现静态资源托管
  • 静态资源托管需要正确设置内容类型
  • 实际项目中,通常使用 Express 等框架来简化服务器开发

现在,你已经了解了如何使用 Node.js 创建 HTTP 服务器,接下来让我们学习请求与响应处理。

© 2026 编程马·菜鸟教程 版权所有