# blog-fastapi
**Repository Path**: miss-tree/blog-fastapi
## Basic Information
- **Project Name**: blog-fastapi
- **Description**: 将之前学的fastapi结合当前博客调整
- **Primary Language**: Python
- **License**: ISC
- **Default Branch**: master
- **Homepage**: None
- **GVP Project**: No
## Statistics
- **Stars**: 0
- **Forks**: 0
- **Created**: 2025-06-25
- **Last Updated**: 2025-11-01
## Categories & Tags
**Categories**: Uncategorized
**Tags**: None
## README
# CORS跨域请求配置说明
## 概述
本项目已配置CORS(跨域资源共享)支持,允许前端应用从不同域名访问FastAPI后端服务。
## 配置说明
### 1. 主要配置文件
- `src/main.py` - 主应用文件,包含CORS中间件配置
- `src/config/cors_config.py` - CORS配置模块,提供灵活的配置选项
### 2. 当前配置
#### 开发环境
- 允许所有来源 (`allow_origins=["*"]`)
- 允许所有HTTP方法
- 允许所有请求头
- 支持认证请求
#### 生产环境
- 需要手动配置允许的域名
- 建议设置具体的允许源以提高安全性
## 使用方法
### 1. 启动服务
```bash
# 使用Docker Compose启动
docker-compose up -d
# 或直接启动Python应用
python src/main.py
```
### 2. 测试CORS功能
#### 方法一:使用提供的测试页面
1. 启动FastAPI服务
2. 在浏览器中打开 `http://localhost:8088/static/cors-test.html`
3. 点击各个测试按钮验证CORS功能
#### 方法二:使用API测试接口
```bash
# GET请求测试
curl -X GET http://localhost:8088/api/test/cors-test
# POST请求测试
curl -X POST http://localhost:8088/api/test/cors-post-test \
-H "Content-Type: application/json" \
-d '{"message": "test"}'
```
### 3. 前端调用示例
#### JavaScript/TypeScript
```javascript
// GET请求
const response = await fetch('http://localhost:8088/api/test/cors-test', {
method: 'GET',
headers: {
'Content-Type': 'application/json',
}
});
// POST请求
const response = await fetch('http://localhost:8088/api/test/cors-post-test', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Authorization': 'Bearer your-token'
},
body: JSON.stringify({
message: 'Hello from frontend',
data: { key: 'value' }
})
});
```
#### React示例
```jsx
import { useState, useEffect } from 'react';
function CorsTest() {
const [data, setData] = useState(null);
useEffect(() => {
const fetchData = async () => {
try {
const response = await fetch('http://localhost:8088/api/test/cors-test');
const result = await response.json();
setData(result);
} catch (error) {
console.error('CORS请求失败:', error);
}
};
fetchData();
}, []);
return (
CORS测试结果
{JSON.stringify(data, null, 2)}
);
}
```
## 配置自定义
### 1. 修改允许的源
编辑 `src/config/cors_config.py` 文件:
```python
# 开发环境允许的源
DEV_ORIGINS = [
"http://localhost:3000", # React开发服务器
"http://localhost:8080", # Vue开发服务器
"http://localhost:4200", # Angular开发服务器
"http://127.0.0.1:3000",
"http://127.0.0.1:8080",
"http://127.0.0.1:4200",
"http://localhost:8088", # FastAPI服务器本身
"http://127.0.0.1:8088",
]
# 生产环境允许的源
PROD_ORIGINS = [
"https://yourdomain.com",
"https://www.yourdomain.com",
"https://api.yourdomain.com",
]
```
### 2. 环境变量配置
设置环境变量来控制CORS行为:
```bash
# 开发环境
export ENVIRONMENT=development
# 生产环境
export ENVIRONMENT=production
```
### 3. Docker环境变量
在 `docker-compose.yml` 中添加环境变量:
```yaml
services:
fastapi-app:
environment:
- ENVIRONMENT=development # 或 production
```
## 安全注意事项
### 1. 生产环境配置
在生产环境中,建议:
1. **不要使用 `allow_origins=["*"]`**
2. **明确指定允许的域名**
3. **限制允许的HTTP方法**
4. **限制允许的请求头**
### 2. 安全配置示例
```python
# 生产环境安全配置
PROD_ORIGINS = [
"https://your-frontend-domain.com",
"https://www.your-frontend-domain.com",
]
ALLOWED_METHODS = [
"GET",
"POST",
"PUT",
"DELETE"
]
ALLOWED_HEADERS = [
"Content-Type",
"Authorization",
"X-Requested-With"
]
```
## 故障排除
### 1. 常见错误
#### CORS错误:No 'Access-Control-Allow-Origin' header
- 检查CORS中间件是否正确配置
- 确认请求的源是否在允许列表中
#### 预检请求失败
- 检查OPTIONS请求是否正确处理
- 确认允许的请求头配置
### 2. 调试方法
1. **检查浏览器控制台**
- 查看网络请求的详细信息
- 检查CORS相关的错误信息
2. **使用测试页面**
- 使用提供的 `cors-test.html` 页面进行测试
3. **检查服务器日志**
- 查看FastAPI应用的日志输出
### 3. 常见问题解决
#### 问题:前端无法发送认证请求
**解决方案:**
```python
# 确保配置中包含认证相关设置
{
"allow_credentials": True,
"allow_headers": ["Authorization", "Content-Type"],
}
```
#### 问题:OPTIONS请求被拒绝
**解决方案:**
```python
# 确保OPTIONS方法在允许列表中
ALLOWED_METHODS = ["GET", "POST", "PUT", "DELETE", "OPTIONS"]
```
## API测试接口
项目提供了以下测试接口:
- `GET /api/test/cors-test` - 基本CORS测试
- `POST /api/test/cors-post-test` - POST请求测试
- `OPTIONS /api/test/cors-options-test` - 预检请求测试
## 更新日志
- **v1.0.0** - 初始CORS配置
- 支持开发和生产环境配置
- 提供完整的测试接口和页面
- 包含安全配置建议
### 数据库创建
```sql
# 创建数据库
CREATE DATABASE blog;
USE blog;
# 创建表
CREATE TABLE comments (
id bigint AUTO_INCREMENT PRIMARY KEY, -- 评论 ID,主键
content TEXT NOT NULL, -- 评论内容
user_id CHAR(36) DEFAULT NULL, -- 评论者用户 ID
username VARCHAR(100) NOT NULL, -- 评论者用户名(冗余字段,避免频繁查询用户表)
post_id CHAR(36) DEFAULT NULL, -- 评论所属的文章 ID
parent_id CHAR(36) DEFAULT NULL, -- 父评论 ID(用于支持嵌套评论)
status ENUM('pending', 'approved', 'deleted') DEFAULT 'pending', -- 评论状态
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, -- 评论创建时间
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, -- 评论更新时间
extradata JSON -- 扩展字段(JSON 格式,支持灵活扩展)
)[comment '评论表'];
# 用户表
CREATE TABLE `user` (
`id` varchar(36) NOT NULL AUTO_INCREMENT COMMENT '用户ID,主键',
`username` varchar(50) NOT NULL COMMENT '用户名',
`password` varchar(255) NOT NULL COMMENT '密码',
`salt` varchar(100) DEFAULT NULL COMMENT '密码盐',
`email` varchar(100) DEFAULT NULL COMMENT '电子邮箱',
`phone` varchar(20) DEFAULT NULL COMMENT '手机号码',
`real_name` varchar(50) DEFAULT NULL COMMENT '真实姓名',
`gender` tinyint(1) DEFAULT 0 COMMENT '性别:0-未知,1-男,2-女',
`birthday` date DEFAULT NULL COMMENT '生日',
`avatar` varchar(255) DEFAULT NULL COMMENT '头像URL',
`status` tinyint(1) DEFAULT 1 COMMENT '状态:0-禁用,1-启用 2-删除',
`is_admin` tinyint(1) DEFAULT 0 COMMENT '是否管理员:0-否,1-是',
`last_login_time` datetime DEFAULT NULL COMMENT '最后登录时间',
`last_login_ip` varchar(50) DEFAULT NULL COMMENT '最后登录IP',
`login_count` int(11) DEFAULT 0 COMMENT '登录次数',
`deleted_at` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '删除时间',
`create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
`update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
`create_by` varchar(36) DEFAULT NULL COMMENT '创建人',
`update_by` varchar(36) DEFAULT NULL COMMENT '更新人',
`remark` varchar(500) DEFAULT NULL COMMENT '备注',
PRIMARY KEY (`id`),
UNIQUE KEY `idx_username` (`username`),
UNIQUE KEY `idx_email` (`email`),
KEY `idx_phone` (`phone`),
KEY `idx_status` (`status`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci COMMENT='用户表';
```