3個月前,我對應用程序編程一無所知,在西班牙待了8個月,我帶著一個想法來到這裡。在來自Antigravity的Gemini AI的支持下,我開始將我關於翻譯語言應用的想法付諸實踐,以便與我在德國的朋友交流。我的流程由4個節點組成(Webhook1+HTTP REQUEST+JavaScript+Respond to Webhook),當我點擊執行工作流時,它在不到3秒內執行,但我的應用程序仍未完成,目前是網頁版本,它從本地存放在我電腦桌面的index文件激活,但它無法完成目標語言的翻譯,最終總是給我返回原始消息;我已經不知道該怎麼辦了
您的工作流在 3 秒內完成執行意味著自動化正在執行,但這並不能證明翻譯輸出已正確傳遞。問題可能不在「翻譯」本身;而很可能是您網頁、webhook、HTTP 請求、JavaScript 節點和最終回應之間的資料對應問題。
我會逐個節點進行偵錯:
-
檢查 Webhook 節點的輸出。確認它接收了原始文本和目標語言。
-
檢查 HTTP Request 節點的輸入。確認它將正確的文本和目標語言傳送到翻譯 API。
-
檢查 HTTP Request 節點的輸出。確認 API 實際返回翻譯後的文本。
-
檢查 JavaScript 節點。它可能在提取錯誤的 JSON 欄位,或者回退到原始訊息。
-
檢查 Respond to Webhook 節點。確認它返回的是
translatedText,而不是原始文本。 -
檢查前端 JavaScript。確認它顯示的是 webhook 回應中的翻譯欄位。
由於您的應用始終返回原始文本,我懷疑存在類似 translatedText || originalText 的回退邏輯,或者回應節點/前端正在顯示原始文本變數。在偵錯時移除回退邏輯,這樣當找不到翻譯時工作流會明確失敗。
翻譯本身應該很簡單。我們已經建立了一個轉錄風格的管線,翻譯文字記錄通常只是另一個處理步驟。更困難的部分是確保正確的變數在整個鏈中移動。如果您分享 Webhook 輸出、HTTP Request 輸出、JavaScript 節點程式碼和前端 fetch 程式碼,我們可能能夠識別確切的中斷點。
從零開始的程式設計知識到建立一個可運作的 webhook 管道是相當令人印象深刻的,所以你不應該放棄,你比你想的更接近成功。
上面的回覆涵蓋了所有的除錯步驟,不過有一件值得補充的事:在這個設置中,「返回原始訊息」最常見的原因是 JavaScript 節點從 API 回應中抓取了錯誤的欄位。
你應該嘗試添加一個 console.log 或使用 n8n 內建的輸出預覽來看看 HTTP Request 節點確實返回了什麼。試著特別查看 JSON 結構。翻譯後的文字通常被嵌套得比預期的更深一層,所以可能會是像 response.data.translations[0].translatedText 這樣的結構,取決於你使用的是哪個 API。
如果你分享你正在呼叫的翻譯 API 是哪個,並貼上使用的 JavaScript 程式碼,有人可能在 2 分鐘內就能找到問題所在。
「非常感謝 @pratham_gupta 和 @AnthonyAtXRay 抽空回覆!你們的除錯要點都非常出色。
為了給你們多一些背景資訊:一開始當我進行初步測試時,整個流程似乎反應良好。不過,瀏覽器中的實際問題最近才開始更明顯地浮現。經過深入分析後,我們懷疑 n8n 的內部邏輯是正常的,但故障發生在最後的通訊階段:我正在以本機方式執行網頁應用程式,直接從我的電腦開啟 index.html 檔案(file://)。一切跡象都指向 Google Chrome 或本機網路政策正在透過 CORS 封鎖來自 n8n IP 位址的回應。
而且,更糟的是,我的 Google API 預付額度剛好用完了,所以流程被暫停了。
為了驗證變數對應是否如你們所建議的那樣精細,我在下方分享我的 JavaScript 節點結構和一般流程(不含認證資訊)。你們認為我的理論——file:// 格式和 CORS 是導致瀏覽器封鎖的罪魁禍首——是否有理?或者你們發現變數邏輯中有什麼錯誤嗎?」
{
“nodes”: [
{
“parameters”: {
“respondWith”: “json”,
“responseBody”: “={{ $json }}”,
“options”: {
“responseCode”: 200,
“responseHeaders”: {
“entries”: [
{
“name”: “Content-Type”,
“value”: “application/json”
},
{
“name”: “Access-Control-Allow-Origin”,
“value”: “"
},
{
“name”: “Access-Control-Allow-Headers”,
“value”: "”
}
]
}
}
},
“type”: “n8n-nodes-base.respondToWebhook”,
“typeVersion”: 1.5,
“position”: [
752,
112
],
“id”: “7eb0364c-e218-47a7-ba7e-f9d8fe8bb8f8”,
“name”: “回應 Webhook”
},
{
“parameters”: {
“httpMethod”: “POST”,
“path”: “98bd0d2c-fcf4-49b7-b501-72c81c5d9d44”,
“responseMode”: “responseNode”,
“options”: {
“allowedOrigins”: “*”
}
},
“type”: “n8n-nodes-base.webhook”,
“typeVersion”: 2.1,
“position”: [
80,
112
],
“id”: “0af6f18b-0e1a-4d5c-bca6-7573f4a31cb9”,
“name”: “Webhook1”,
“webhookId”: “c1603781-563f-4655-9b6d-1170e847c6f0”
},
{
“parameters”: {
“method”: “POST”,
“url”: “https://generativelanguage.googleapis.com/v1/models/gemini-2.5-flash:generateContent?key=TU_API_KEY_AQUÍ”,
“sendBody”: true,
“specifyBody”: “json”,
“jsonBody”: “={{ { “contents”: [{ “parts”: [{ “text”: $json.body.text + " - 將此翻譯為 " + $json.body.target_lang }] }] } }}”,
“options”: {}
},
“id”: “06da87ea-d639-41fa-a859-50ae26c35224”,
“name”: “HTTP 請求”,
“type”: “n8n-nodes-base.httpRequest”,
“typeVersion”: 4.4,
“position”: [
304,
112
]
},
{
“parameters”: {
“jsCode”: “const geminiResponse = $input.first().json;\nconst translatedText = geminiResponse.candidates[0].content.parts[0].text.trim();\n\nreturn [\n {\n json: {\n status: “success”,\n original_text: $(‘Webhook1’).item.json.body.text,\n translated_text: translatedText,\n audio_base64: “”\n }\n }\n];”
},
“id”: “576fa8a4-896f-4d33-ad1a-8cfe5d204ec8”,
“name”: “JavaScript 程式碼”,
“type”: “n8n-nodes-base.code”,
“typeVersion”: 2,
“position”: [
528,
112
]
}
],
“connections”: {
“Webhook1”: {
“main”: [
[
{
“node”: “HTTP 請求”,
“type”: “main”,
“index”: 0
}
]
]
},
“HTTP 請求”: {
“main”: [
[
{
“node”: “JavaScript 程式碼”,
“type”: “main”,
“index”: 0
}
]
]
},
“JavaScript 程式碼”: {
“main”: [
[
{
“node”: “回應 Webhook”,
“type”: “main”,
“index”: 0
}
]
]
}
},
“pinData”: {},
“meta”: {
“templateCredsSetupCompleted”: true,
“instanceId”: “ANONYMOUS_INSTANCE_ID”
}
}
Freddy,截圖會有幫助,但根據你的描述,我會把問題縮小到一個具體的問題:
翻譯後的文字在哪個環節消失了?
你的 n8n 工作流程可能運行正常,但網頁應用程式可能仍在讀取錯誤的欄位。
我會按這個順序進行測試:
- Webhook 節點
確認傳入的資料包含類似這樣的內容:
{
"text": "hello",
"targetLanguage": "German"
}
- HTTP Request 節點
開啟節點執行輸出,檢查翻譯 API 是否回傳了翻譯後的文字。
例如,類似這樣:
{
"translatedText": "Hallo"
}
或有時可能會更深層地嵌套,像這樣:
{
"data": {
"translation": "Hallo"
}
}
- JavaScript 節點
這是常見的中斷點。程式碼可能在讀取錯誤的欄位。
為了除錯,不要將原始訊息作為備用方案回傳。改為回傳一個明顯的錯誤:
const output = $json.translatedText;
if (!output) {
throw new Error("No translated text found. Check HTTP Request output field name.");
}
return [
{
json: {
translatedText: output
}
}
];
如果翻譯後的文字是嵌套的,你需要根據實際的 HTTP Request 輸出來調整欄位路徑。
- Respond to Webhook 節點
確保它回傳的是翻譯後的值,而不是原始輸入。
回應範例:
{
"translatedText": "={{$json.translatedText}}"
}
- 前端提取程式碼
你的本地網頁可能在做這樣的事:
resultBox.innerText = data.text;
但實際上應該是:
resultBox.innerText = data.translatedText;
因為你的應用程式總是回傳原始訊息,我最有把握的猜測是以下其中一個:
-
JavaScript 節點回退到了原始文字
-
Respond to Webhook 節點對應到了原始欄位
-
前端顯示的是原始欄位而不是翻譯後的欄位
-
HTTP Request 節點以嵌套的 JSON 路徑回傳翻譯,但 JS 節點讀取的是錯誤的路徑
最佳除錯做法:暫時直接從 Respond to Webhook 回傳完整的 HTTP Request 輸出。然後從網頁應用程式測試,檢查你的瀏覽器實際收到了什麼。一旦你看到真實的 JSON 結構,對應翻譯後的欄位應該就很容易了。
你對CORS的理論完全正確,你的工作流JSON暴露了具體的問題。
你的Webhook節點的「allowedOrigins」設定為「asterisk」,這是應該的。但是你的「Respond to Webhook」節點的「Access-Control-Allow-Origin」設定為空字符串。這需要改為「asterisk」,否則即使請求通過,Chrome也會阻止回應。
下一個問題是file://協議本身。Chrome最終會阻止從file://頁面到外部URL的fetch請求,不管CORS標頭如何。修復很簡單——不要直接開啟index.html,改為從本地伺服器提供。
如果你已安裝Python:在包含index.html的資料夾中執行python -m http.server 8080,然後開啟http://localhost:8080
至於Google API額度,填完後,JavaScript節點邏輯本身看起來是正確的。而且變數映射到candidates[0].content.parts[0].text是Gemini回應的正確路徑。