- Database schema with MySQL support - LLM API integration (Gemini 2.5 Flash, DeepSeek, OpenAI) - Error handling with copyable error messages - CORS fix for API calls - Complete setup documentation 🤖 Generated with Claude Code https://claude.com/claude-code Co-Authored-By: Claude <noreply@anthropic.com>
8.1 KiB
CORS 錯誤修正指南
🔴 問題說明
您遇到的錯誤有兩個:
1. CORS (跨域資源共享) 錯誤
Access to fetch at 'https://api.anthropic.com/v1/messages' from origin 'http://127.0.0.1:5000'
has been blocked by CORS policy: Response to preflight request doesn't pass access control check:
No 'Access-Control-Allow-Origin' header is present on the requested resource.
原因: 前端代碼直接從瀏覽器調用 Claude API,但 Claude API 不允許來自瀏覽器的直接請求(出於安全考量)。
2. Storage 訪問錯誤
Uncaught (in promise) Error: Access to storage is not allowed from this context.
原因: 瀏覽器的本地存儲權限問題,通常在使用 file:// 協議或某些安全限制下出現。
✅ 解決方案
方案 1: 修改 index.html 中的 callClaudeAPI 函數(推薦)
步驟 1: 打開 index.html
步驟 2: 找到第 1264 行的 callClaudeAPI 函數
步驟 3: 將整個函數替換為以下代碼:
// ==================== AI Generation Functions ====================
async function callClaudeAPI(prompt, api = 'gemini') {
try {
// 調用後端 Flask API,避免 CORS 錯誤
const response = await fetch("/api/llm/generate", {
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify({
api: api, // 使用指定的 LLM API (gemini, deepseek, openai)
prompt: prompt,
max_tokens: 2000
})
});
if (!response.ok) {
const errorData = await response.json();
throw new Error(errorData.error || `API 請求失敗: ${response.status}`);
}
const data = await response.json();
if (!data.success) {
throw new Error(data.error || 'API 調用失敗');
}
// 解析返回的文字為 JSON
let responseText = data.text;
responseText = responseText.replace(/```json\n?/g, "").replace(/```\n?/g, "").trim();
return JSON.parse(responseText);
} catch (error) {
console.error("Error calling LLM API:", error);
// 顯示友好的錯誤訊息
alert(`AI 生成錯誤: ${error.message}\n\n請確保:\n1. Flask 後端已啟動\n2. 已在 .env 文件中配置 LLM API Key\n3. 網路連線正常`);
throw error;
}
}
步驟 4: 保存文件
步驟 5: 確保使用更新版的 Flask 後端
# 使用包含 LLM 端點的版本
python app_updated.py
步驟 6: 重新載入瀏覽器頁面
方案 2: 使用已修正的文件(快速方案)
我已經創建了包含完整修正的文件,您可以選擇以下方式之一:
選項 A: 手動修改(最安全)
- 打開
index.html - 搜尋
async function callClaudeAPI(prompt) - 用上面方案 1 的代碼替換
選項 B: 使用腳本自動修正
參考 fix_cors.js 文件中的完整說明。
📋 完整修正步驟
1. 確認後端已啟動並包含 LLM 端點
# 停止當前運行的 Flask(如果有)
# 按 Ctrl+C
# 啟動更新版後端
python app_updated.py
您應該看到:
✓ LLM 功能已啟用
已配置的 API: gemini, deepseek, openai
2. 配置 LLM API Key
編輯 .env 文件,添加至少一個 API Key:
# 至少配置其中一個
GEMINI_API_KEY=your_actual_gemini_api_key_here
DEEPSEEK_API_KEY=your_actual_deepseek_api_key_here
OPENAI_API_KEY=your_actual_openai_api_key_here
獲取 API Key:
- Gemini: https://makersuite.google.com/app/apikey
- DeepSeek: https://www.deepseek.com/
- OpenAI: https://platform.openai.com/api-keys
3. 測試 LLM API 連線
訪問測試頁面:http://localhost:5000/api-test
點擊「測試連線」按鈕,確保至少一個 API 顯示「✓ 連線成功」。
4. 修改 index.html
按照方案 1 的步驟修改 callClaudeAPI 函數。
5. 重新載入頁面
在瀏覽器中按 Ctrl+F5 強制重新載入頁面(清除緩存)。
6. 測試 AI 功能
- 在主頁面點擊「新增崗位」
- 填寫部分欄位(例如崗位名稱)
- 點擊「✨ I'm feeling lucky」按鈕
- 應該會成功生成內容,不再出現 CORS 錯誤
🔍 驗證修正是否成功
打開瀏覽器的開發者工具(F12),切換到 Console 標籤:
✅ 成功的表現:
- 沒有 CORS 錯誤
- 看到
POST http://localhost:5000/api/llm/generate請求成功 (200 OK) - AI 自動填充正常工作
❌ 仍有問題:
如果看到 403 LLM 功能未啟用
原因: 沒有使用 app_updated.py
解決:
python app_updated.py
如果看到 API Key 未設定
原因: .env 文件中沒有配置 API Key
解決: 編輯 .env 文件,添加有效的 API Key
如果看到 連線逾時
原因: 網路連線問題或 API 伺服器問題 解決:
- 檢查網路連線
- 嘗試使用不同的 LLM API(修改
callClaudeAPI(prompt, 'deepseek'))
如果看到 API Key 無效
原因: API Key 錯誤或已過期 解決: 重新獲取有效的 API Key
🎯 架構變更說明
修正前(錯誤):
瀏覽器 → 直接調用 → Claude API (❌ CORS 錯誤)
修正後(正確):
瀏覽器 → Flask 後端 → Gemini/DeepSeek/OpenAI API (✅ 正常)
💡 為什麼這樣修改
1. 安全性
- API Key 保護: API Key 只存儲在服務器端(.env 文件),不暴露給前端
- 防止濫用: 用戶無法看到或竊取 API Key
2. CORS 問題
- 同源請求: 前端只調用同域的 Flask API(http://localhost:5000)
- 服務器端請求: Flask 服務器調用外部 API,不受 CORS 限制
3. 靈活性
- 多 API 支持: 可以輕鬆切換不同的 LLM API
- 統一接口: 前端代碼無需關心使用哪個 LLM API
📝 其他建議
1. 添加錯誤處理 UI
在 <head> 標籤中添加錯誤處理腳本:
<script src="error_handler.js"></script>
2. 選擇 LLM API
如果想使用特定的 LLM API,可以修改調用:
// 使用 Gemini(默認)
const result = await callClaudeAPI(prompt, 'gemini');
// 使用 DeepSeek
const result = await callClaudeAPI(prompt, 'deepseek');
// 使用 OpenAI
const result = await callClaudeAPI(prompt, 'openai');
3. 添加 API 選擇器
可以在前端添加一個下拉選單,讓用戶選擇使用哪個 LLM API:
<select id="llm-selector">
<option value="gemini">Google Gemini</option>
<option value="deepseek">DeepSeek</option>
<option value="openai">OpenAI</option>
</select>
然後在調用時使用:
const api = document.getElementById('llm-selector').value;
const result = await callClaudeAPI(prompt, api);
🆘 仍然遇到問題?
檢查清單
- Flask 後端是否正在運行?
- 是否使用
app_updated.py而不是app.py? - .env 文件中是否配置了至少一個 API Key?
- API Key 是否有效?(可以在 http://localhost:5000/api-test 測試)
- 是否已修改 index.html 中的
callClaudeAPI函數? - 瀏覽器是否已重新載入頁面(Ctrl+F5)?
- 瀏覽器控制台是否還有其他錯誤?
調試步驟
-
測試後端 API:
curl -X POST http://localhost:5000/api/llm/generate \ -H "Content-Type: application/json" \ -d '{"api":"gemini","prompt":"測試","max_tokens":100}' -
檢查 Flask 日誌: 查看終端中 Flask 的輸出
-
瀏覽器控制台: 查看詳細的錯誤訊息
-
測試頁面: 訪問 http://localhost:5000/api-test 確認 API 配置
📚 相關文件
- SETUP.md - 完整安裝指南
- fix_cors.js - 詳細修正代碼
- error_handler.js - 全局錯誤處理
- app_updated.py - 包含 LLM 端點的 Flask 後端
文件版本: 1.0 最後更新: 2024-12-04 問題類型: CORS 跨域請求錯誤 解決狀態: ✅ 已提供完整解決方案