在Web开发中,前后端分离架构已经成为主流。前端负责页面展示,后端专注于业务逻辑和数据处理,两者通过API接口通信。但如何让前端页面和后端服务和谐工作,避免复杂的跨域问题,并且让用户访问更便捷?这时,Nginx的反向代理功能就能派上大用场。

一、什么是反向代理?

先从基础概念说起。我们先回忆一下正向代理:比如你需要访问国外网站,直接访问不了,于是通过VPN(虚拟专用网络)代理你的请求,这就是正向代理。此时VPN代理的是客户端,你不知道目标服务器的真实地址。

反向代理则相反,它代理的是服务器。用户访问的是反向代理服务器(比如Nginx),但反向代理服务器会根据请求内容,将请求转发到后端真实的服务器上。对用户来说,反向代理服务器就像后端服务器本身,用户不需要知道后端服务的具体地址。

二、为什么前后端分离需要反向代理?

假设你有一个前端项目(比如Vue或React)和一个后端API服务(比如Node.js或Java),它们可能运行在不同的服务器或端口上。没有反向代理时,用户需要分别访问前端和后端地址(例如http://frontend.comhttp://backend.com/api),这样会带来几个问题:

  1. 域名管理复杂:用户需要记住多个域名。
  2. 跨域问题:前端直接调用不同域名的后端接口会触发浏览器的跨域限制。
  3. 安全隐患:直接暴露后端服务地址,增加被攻击风险。

而反向代理可以解决这些问题:
- 统一域名:用户只需要访问一个域名(例如https://example.com)。
- 隐藏后端:用户请求被Nginx拦截后转发到后端,后端地址对用户透明。
- 路径代理:不同路径请求(如/对应前端,/api对应后端)由Nginx自动分配。

三、Nginx安装与基本配置

1. 安装Nginx

以Ubuntu为例,安装命令:

sudo apt update
sudo apt install nginx

CentOS用户:

sudo yum install nginx

Windows用户可从Nginx官网下载安装包,按提示安装。

2. 启动与验证

安装完成后,启动Nginx:

sudo systemctl start nginx

检查状态:

sudo systemctl status nginx

此时访问服务器IP或域名(如http://localhost),能看到Nginx的默认欢迎页面,说明安装成功。

四、反向代理实战:前端+后端分离配置

假设我们有两个服务:
- 前端服务:静态HTML文件(放在Nginx的/usr/share/nginx/html目录下)。
- 后端服务:一个简单的Node.js API服务,运行在本地3000端口(返回{"message": "Hello from backend"})。

1. 准备前端静态文件

在Nginx的默认网站目录(Ubuntu/CentOS通常是/usr/share/nginx/html)下创建前端页面:

sudo nano /usr/share/nginx/html/index.html

写入简单内容:

<!DOCTYPE html>
<html>
<body>
  <h1>前端页面</h1>
  <p>点击按钮调用后端接口:</p>
  <button onclick="callBackend()">调用API</button>
  <script>
    function callBackend() {
      fetch('/api/user')
        .then(res => res.json())
        .then(data => alert(data.message));
    }
  </script>
</body>
</html>

2. 启动后端服务

用Node.js创建一个简单的后端服务(需先安装Node.js):

# 创建项目目录
mkdir backend && cd backend
# 初始化项目
npm init -y
# 安装Express
npm install express

创建app.js

const express = require('express');
const app = express();
const port = 3000;

app.get('/user', (req, res) => {
  res.json({ message: 'Hello from backend!' });
});

app.listen(port, () => {
  console.log(`后端服务运行在 http://localhost:${port}`);
});

启动后端:

node app.js

3. 配置Nginx反向代理

编辑Nginx配置文件,将请求转发到前端或后端:

sudo nano /etc/nginx/sites-available/default

server块中添加以下配置(完整配置参考下方示例):

server {
    listen 80;
    server_name localhost;  # 替换为你的域名或服务器IP

    # 前端静态资源:所有路径(除/api外)都指向前端页面
    location / {
        root /usr/share/nginx/html;  # 前端文件目录
        index index.html;            # 默认首页
        try_files $uri $uri/ /index.html;  # 支持前端路由(如/#/about)
    }

    # 后端API:所有以/api开头的请求转发到后端服务
    location /api {
        proxy_pass http://localhost:3000;  # 后端服务地址
        proxy_set_header Host $host;       # 传递Host头,让后端知道请求来源
        proxy_set_header X-Real-IP $remote_addr;  # 传递真实IP
    }
}

4. 验证配置并重启Nginx

测试配置是否有误:

sudo nginx -t

若提示test is successful,则重启Nginx:

sudo systemctl restart nginx

5. 测试效果

  • 访问http://localhost(或你的域名),能看到前端页面。
  • 点击页面上的“调用API”按钮,会触发fetch('/api/user'),此时Nginx会将请求转发到后端服务http://localhost:3000/user,并返回数据。

五、核心配置解析

1. location

Nginx通过location定义不同路径的处理规则。常用匹配方式:
- location /:匹配所有路径(需放在其他location前面)。
- location /api:匹配以/api开头的路径。

2. proxy_pass

proxy_pass用于指定转发的目标地址,格式为http://目标IP:端口。例如:

location /api {
    proxy_pass http://127.0.0.1:3000;  # 也可写localhost:3000
}

3. proxy_set_header

传递HTTP头信息给后端,常见场景:
- Host $host:后端获取真实请求域名。
- X-Real-IP $remote_addr:后端获取用户真实IP(避免后端日志显示Nginx的IP)。

六、常见问题与解决

  1. Nginx启动失败
    nginx -t检查配置语法,错误信息通常会指出问题行。

  2. 前端资源404
    确保root路径和index文件存在,例如:

   location / {
       root /usr/share/nginx/html;  # 路径必须正确
       index index.html;            # 文件必须存在
   }
  1. 后端接口无法访问
    检查后端服务是否启动,端口是否被占用,proxy_pass是否写对地址(如http://localhost:3000而非localhost:3000)。

七、总结

反向代理是Nginx的核心功能之一,尤其在前后端分离架构中,它能帮我们:
- 隐藏后端服务地址,提升安全性。
- 统一域名和路径,简化用户访问。
- 集中管理请求转发,便于后续扩展(如负载均衡、缓存)。

通过本文的示例,你已经可以快速上手配置反向代理,让前端和后端服务无缝协作。接下来可以尝试将后端服务换成Java、Python等其他技术栈,或进一步学习Nginx的缓存、SSL配置等高级功能。

小夜