2026-04-29-22-37-36 - 修复登录ERR_CONNECTION_REFUSED:前端baseURL改IP+后端CORS扩origin

This commit is contained in:
2026-04-29 22:41:10 +08:00
parent f41d9c20f5
commit 0f7b1ec31d
7 changed files with 166 additions and 2 deletions

Binary file not shown.

View File

@@ -24,7 +24,7 @@ class Settings(BaseSettings):
# App
app_env: str = "development"
cors_origins: list[str] = ["http://localhost:3000"]
cors_origins: list[str] = ["http://localhost:3000", "http://192.168.3.11:3000"]
class Config:
env_file = ".env"

View File

@@ -2,7 +2,7 @@ import axios, { AxiosError } from 'axios';
import type { Project, Template } from '../store/useStore';
const apiClient = axios.create({
baseURL: 'http://localhost:8000',
baseURL: 'http://192.168.3.11:8000',
headers: {
'Content-Type': 'application/json',
},

View File

@@ -0,0 +1,46 @@
# 实现方案 - 2026-04-29-22-37-36
## 对应需求
- 需求分析文档: `需求分析-2026-04-29-22-37-36.md`
## 方案概述
服务器实际 IP 为 `192.168.3.11`。修复方案分三步:
1. 前端 `api.ts``baseURL` 改为服务器实际 IP
2. 后端 CORS 配置添加服务器 IP 对应的前端 origin
3. 重启前后端服务验证
## 根因分析
```
用户浏览器 → 访问 http://192.168.3.11:3000前端
↓ 前端代码运行
↓ api.ts 中 axios.post('http://localhost:8000/api/auth/login')
↓ 浏览器解析 localhost = 用户本地机器(非服务器)
↓ 用户本地 8000 端口无服务
↓ ERR_CONNECTION_REFUSED
```
## 修改文件清单
### 文件 1: `src/lib/api.ts`(修改)
- **修改类型**: 修改 baseURL
- **修改内容**: `http://localhost:8000``http://192.168.3.11:8000`
### 文件 2: `backend/config.py`(修改)
- **修改类型**: 扩展 CORS origins
- **修改内容**: `cors_origins``["http://localhost:3000"]` 扩展为 `["http://localhost:3000", "http://192.168.3.11:3000"]`
### 文件 3: `.env.example`(新增/修改)
- **修改类型**: 新增 VITE_API_BASE_URL 示例
- **修改内容**: 提供前端 baseURL 环境变量模板
## 新增依赖
## 兼容性分析
- localhost:3000 开发方式仍可用CORS 双 origin
- 局域网 IP 访问方式新增可用
- 回滚策略: 改回 localhost 即可
## 预估工作量
- 代码修改: 5 分钟
- 重启验证: 5 分钟

View File

@@ -0,0 +1,51 @@
# 测试方案 - 2026-04-29-22-37-36
## 对应实现方案
- 实现方案文档: `实现方案-2026-04-29-22-37-36.md`
## 测试范围
- 前端 baseURL 修改后 API 可达性
- 后端 CORS 跨域请求是否通过
- 登录功能端到端验证
## 测试用例
### 用例 1: 后端 CORS 预检验证
- **前置条件**: 后端已重启
- **操作步骤**:
```bash
curl -s -X OPTIONS http://192.168.3.11:8000/api/auth/login \
-H "Origin: http://192.168.3.11:3000" \
-H "Access-Control-Request-Method: POST" \
-i | grep -i "access-control-allow-origin"
```
- **预期结果**: 返回 `Access-Control-Allow-Origin: http://192.168.3.11:3000`
- **通过标准**: CORS 头存在且值正确
### 用例 2: 前端 API 直连测试
- **前置条件**: 后端运行中
- **操作步骤**:
```bash
curl -s -X POST http://192.168.3.11:8000/api/auth/login \
-H "Content-Type: application/json" \
-d '{"username":"admin","password":"123456"}'
```
- **预期结果**: 返回 `{"token":"fake-jwt-token-for-admin","username":"admin"}`
- **通过标准**: HTTP 200返回正确 JSON
### 用例 3: 登录端到端验证(浏览器)
- **前置条件**: 前后端均运行
- **操作步骤**:
1. 浏览器访问 `http://192.168.3.11:3000`
2. 输入 admin / 123456
3. 点击登录
- **预期结果**: 登录成功,进入工作区界面
- **通过标准**: 无 `ERR_CONNECTION_REFUSED` 报错,页面跳转正常
## 回归测试
- [ ] localhost:3000 访问方式仍可用
- [ ] 后端其他 API/api/projects 等)跨域正常
## 测试环境
- 浏览器: Chrome
- 访问地址: http://192.168.3.11:3000

View File

@@ -117,4 +117,29 @@ AI 助手运行的容器/环境与项目实际开发环境分离,后者才装
---
## 2026-04-29-22-37-36 — 登录报错 ERR_CONNECTION_REFUSED
### A. 具体问题
用户通过浏览器访问前端并点击登录时,控制台报错 `POST http://localhost:8000/api/auth/login net::ERR_CONNECTION_REFUSED`,登录失败。
### B. 产生原因
1. 前端 `api.ts``baseURL` 硬编码为 `http://localhost:8000`
2. 用户通过局域网 IP`http://192.168.3.11:3000`)访问前端,而非 `http://localhost:3000`
3. 浏览器运行前端代码时,将 `localhost` 解析为**用户本地机器**(而非服务器),向用户本地 8000 端口发请求
4. 用户本地 8000 端口无服务TCP 连接被拒绝
5. 同时后端 CORS 配置仅允许 `http://localhost:3000`,未允许 IP 地址访问
### C. 解决方案
1.`src/lib/api.ts``baseURL``http://localhost:8000` 改为服务器实际 IP `http://192.168.3.11:8000`
2.`backend/config.py``cors_origins``["http://localhost:3000"]` 扩展为 `["http://localhost:3000", "http://192.168.3.11:3000"]`
3. 重启后端服务使 CORS 生效,重新构建前端使 baseURL 生效
### D. 后续如何避免问题
1. 部署时统一使用服务器实际 IP 替代 localhost避免浏览器端解析歧义
2. 前端 baseURL 应支持环境变量配置(如 `VITE_API_BASE_URL`),不同环境注入不同值
3. 后端 CORS origins 应使用配置化列表,支持开发/测试/生产多环境
4. 在 README 中明确说明访问地址,提醒用户必须使用服务器 IP 而非 localhost
---
> 新增经验请追加到文件末尾,保持时间倒序或正序均可,但需确保每条经验包含完整的 A/B/C/D 四段。

View File

@@ -0,0 +1,42 @@
# 需求分析 - 2026-04-29-22-37-36
## 需求来源
- 提出时间: 2026-04-29-22-37-36
- 需求类型: 缺陷修复
## 原始需求描述
用户登录失败,浏览器控制台报错:
```
POST http://localhost:8000/api/auth/login net::ERR_CONNECTION_REFUSED
```
## 需求拆解
### 需求 1: 修复前端 baseURL 配置
- **详细描述**: `src/lib/api.ts``baseURL` 硬编码为 `http://localhost:8000`,当用户通过非 localhost 地址访问前端时,浏览器将 localhost 解析为客户端本地机器而非服务器,导致连接拒绝
- **优先级**: P0-阻塞
- **影响范围**: `src/lib/api.ts`
- **验收标准**: 前端可通过局域网 IP 正确访问后端
### 需求 2: 修复后端 CORS 配置
- **详细描述**: `backend/config.py``cors_origins` 仅允许 `http://localhost:3000`,需添加服务器实际 IP 地址的前端 origin
- **优先级**: P0-阻塞
- **影响范围**: `backend/config.py`, `backend/main.py`
- **验收标准**: 后端接受来自服务器 IP:3000 的跨域请求
### 需求 3: 添加 baseURL 可配置机制(可选增强)
- **详细描述**: 通过 `.env` 或运行时代码自动检测服务器 IP使 baseURL 不再硬编码
- **优先级**: P1-高
- **影响范围**: `src/lib/api.ts`
- **验收标准**: 无需修改代码即可适配不同部署环境
## 约束条件
- 不破坏现有 localhost 开发体验
- 保持中文界面不变
- 最小修改原则
## 风险评估
| 风险点 | 影响 | 缓解措施 |
|--------|------|----------|
| 修改后 localhost 开发失效 | 高 | 同时保留 localhost 和 IP 两种访问方式 |
| CORS 配置过于宽泛 | 中 | 仅添加必要的 IP origin不开放通配符 |