我们好不容易写了一个网站项目,满心欢喜的想让别人也用用,发给对方"http://localhost:3000""http://127.0.0.1:3000"这种网址,结果人家一打开出现无法访问的页面,你一看又以为自己代码报错了。实际上是你没懂以下知识:

一、为什么我本地能打开网页,别人/外网无法访问?

1.网址访问核心原理

首先我们要明白(localhost/127.0.0.1)是本地地址,即只有自己电脑可访问,是电脑内部循环地址,外网用户、其他设备完全连不上;

其次如果我们处于同一局域网下,使用(192.168.x.x)局域网地址就可以让同一WiFi/局域网设备可访问,但外网无法穿透;

最后是服务器公网IP,使用这种地址全网都可以进行访问,是真正的上线公开地址。

2.前端的两种启动方式

那么就有人问了,“我平时启动只会有(localhost/127.0.0.1)这种本地地址”,这就要提到前端的环境了。

  • 开发环境npm start / npm run dev)

平时启动前端我们都用这种命令启动,而本地开发调试就应该这么启动,开发环境支持热更新、调试代码、实时编译等特性,不过使用npm run dev默认监听 localhost/127.0.0.1只能本机打开,同 WiFi 别的手机 / 电脑打不开

也可以改成局域网可访问命令

# vite/react-ts项目, 0.0.0.0 = 监听本机所有网卡,本机、局域网全都能连。
npm run dev -- --host 0.0.0.0

启动后终端会出现:http://192.168.x.x:3000

同局域网设备输入这个内网 IP 就能访问页面。

  • 生产打包环境npm run build

使用这串命令就可以将零散的React源码、JS/CSS文件压缩、合并、去除调试代码,生成纯静态的 dist文件夹,这个打包的dist文件夹是专门用于服务器上线,下面也会讲到如何使用这个 dist 文件夹。

二、我的前端网页怎么不能调用后端API?

1.跨域处理

有的小伙伴可能发现开发环境下,往往后端需要开启CORS跨域中间件,前端才能正常访问后端API服务。

那么跨域是什么?跨域是浏览器的安全限制,和代码、服务器无关,

若前端的访问网址(协议、域名、端口)和后端的访问网址(协议、域名、端口)任意不一致,都会导致浏览器拒绝发送请求。

默认前端3000,后端8000的端口(天然跨域),因此在开发调试的环境下后端代码必须添加跨域处理

# python FastAPI
from fastapi.middleware.cors import CORSMiddleware

# 允许的源(可以是域名列表)
origins = [
    "http://localhost",
    "http://localhost:3000"
]

# 全局配置 CORS 中间件
app.add_middleware(
    CORSMiddleware,
    allow_origins=origins,
    allow_credentials=True, # 允许携带 Cookie
    allow_methods=["*"],    # 允许的 HTTP 请求方法
    allow_headers=["*"],    # 允许的 HTTP 请求头
)

2.Nginx反向代理

上面提到的跨域,只在开发环境下后端需要配置。

而在生产打包环境,即项目上线阶段,我们只需要使用Nginx反向代理,后端可以完全删除CORS跨域代码

本文推荐使用 Docker 容器 Nginx:这里先给出 nginx.conf 配置文件模版

# nginx.conf
server {
    listen 80;
    root /usr/share/nginx/html;
    index index.html;

    # React路由刷新404处理
    location / {
        try_files $uri $uri/ /index.html;
    }

    # 反向代理/api到后端容器
    location /api/ {
        # backend = compose里后端服务名称,Docker内网域名,不用IP
        proxy_pass http://backend:8000/;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
    }
}

Nginx反向代理 后,前端的接口统一请求 /api/xxx (不再需要前置URL:IP、端口),并且请求会先到达Nginx,

然后Nginx在服务器内网,悄悄将请求转发给后端,而服务器内部转发不受浏览器跨域限制,完美解决跨域报错。

三、如何让别人/外网正常使用网页的全部功能?

看到这里,相信你已经了解:

  • 在开发环境下,通过本地/局域网地址让别人访问前端网页,也通过跨域处理可以调用后端API,最终在本地跑通一个项目的全流程。
  • 也知道项目上线需要先生产环境将前端打包成dist文件夹,还要通过Nginx反向代理前端接口请求,解决跨域问题。

那么如何才能让别人/外网正常访问并使用网页的全部功能呢?这就需要将项目部署到服务器上。

1.Docker部署

将项目部署到服务器上,意味着将所有代码托管到服务器上运行,但本地电脑环境和服务器环境不一致,依赖版本冲突、Python/Node/Nginx配置报错,导致本地能跑、服务器却报错。

Docker的作用就是把**代码+依赖+运行环境 **都打包成独立容器,服务器就不需要考虑这些运行环境和配置,可以实现本地能跑,服务器就能跑。

搭配 docker-compose 实现前后端容器统一编排管理。

2.配置服务器

  • 使用云服务器 / 物理机都可以。

  • 由于我们采用 Docker 进行部署,所以只需要安装 Docker 与 Compose:

# 一键安装docker官方脚本
curl -fsSL https://get.docker.com | sh
# 设置docker开机自启
systemctl enable docker
# 启动docker服务
systemctl start docker

安装完成自动附带 docker compose 插件,无需额外安装 compose。

  • 需要将服务器防火墙的 80 端口放行(网页访问端口)
# CentOS系统放行80永久生效
firewall-cmd --add-port=80/tcp --permanent
# 重载防火墙规则
firewall-cmd --reload

# Ubuntu系统放行80
ufw allow 80

因为在服务器上运行后,浏览器前端的访问端口默认是80。

  • 云服务器还需要额外配置:登录阿里云 / 腾讯云后台→安全组,入方向放行80端口

3.完整上线闭环流程

  1. 本地前端:执行 npm run build 打包生成 dist 文件夹
  2. 本地后端:删除生产无用的CORS跨域代码
  3. 把 dist、后端文件夹上传服务器新建项目文件夹
project/
├─ frontend/
│  ├─ dist/         # 前端npm run build产物
│  ├─ nginx.conf    # Nginx反向代理配置
│  └─ Dockerfile    # 前端镜像构建配置
├─ backend/
│  ├─ main.py       # FastAPI主程序
│  ├─ requirements.txt # python依赖
|  ├─ .py文件/文件夹
│  └─ Dockerfile    # 后端镜像构建配置
└─ docker-compose.yml # 容器编排配置
  1. 在项目文件夹创建 3 个配置文件:前端 Dockerfile、后端 Dockerfile、docker-compose.yml

  2. 服务器执行:docker compose up -d --build 一键部署

  3. 浏览器输入服务器公网 IP 直接访问网站

Logo

openEuler 是由开放原子开源基金会孵化的全场景开源操作系统项目,面向数字基础设施四大核心场景(服务器、云计算、边缘计算、嵌入式),全面支持 ARM、x86、RISC-V、loongArch、PowerPC、SW-64 等多样性计算架构

更多推荐