網站搜尋

javascript - 「一個監聽器透過返回 true 表示非同步回應,但在收到回應之前訊息通道已經關閉」,這是什麼意思?


我正在開發一個 React 應用程式,我使用了一些 npm 模組,其中一個是我自己建立的。(我的 NPM 套件:https://www.npmjs.com/package/modale-react-rm)。

這是一個簡單的模態視窗,使用 useState() 來開啟和關閉。

在匯入我的套件後,我的控制台出現了一個錯誤,這個錯誤在幾秒鐘後突然出現,而我並沒有執行任何操作。

Uncaught (in promise)                                                                  localhost/:1

    >{message: 'A listener indicated an asynchronous response by r…age channel closed before a response was received'}
         message: "A listener indicated an asynchronous response by returning true, but the message channel closed before a response was received"
        >[[Prototype]]: Object
             >constructor: ƒ ()
             >[[Prototype]]: Object

       /* sometimes there are specific elements in addition but I could not check when they appear and when not */

            Promise.then (asynchrone)       
            (anonyme)              @content_script_bundle.js:108
            handleNewFeatures      @content_script_bundle.js:101
            handleUpdatedNodes     @content_script_bundle.js:101
            (anonyme)              @content_script_bundle.js:101
            childlist(asynchrone)
            0                      @purplebox.js:1
            (anonyme)              @purplebox.js:1
            v                      @purplebox.js:1

它不會阻擋我的頁面,也不會影響其功能的正常運作,但這是一個錯誤,我認為應該修復,或許還能幫助其他有相同問題的人。

我特別說明,我在這個專案中沒有進行任何非同步請求。所有資料都是本地的,我使用的少量資料都是直接以原始形式匯入的。我也不知道 Purplebox.js 是從哪裡來的。

答案#1

這個問題是跨來源請求問題,並且是由各種 Chrome 擴充功能引起的。我在我的 Angular 應用中也遇到過這個問題,在隱身模式下測試後,錯誤就不再出現了。

更多資訊:Google 論壇

如果你是來這裡的擴充功能開發者:你需要將你的跨來源抓取請求從內容腳本移動到你的擴充功能的背景頁面,並從內容腳本中呼叫它。內容腳本中的跨來源抓取不再被允許。不要忘記在請求結尾加上 return true。更多資訊和範例:Chromium Project

答案#2

就我而言,這是由 Ghostery 擴充功能引起的,如果這個錯誤出現在你的本地主機,你需要將其加入 Ghostery 的受信任網站列表,錯誤就會消失。

答案#3

背景腳本(MV3 中的服務工作者)可能會進入非活動狀態,而不回應它從內容腳本接收到的訊息。

範例:

背景腳本:

chrome.runtime.onMessage.addListener((request, sender, sendResponse) => {
  // ... handle message
  return true // Error message says you already return true
})

大多數 MV3 API 是非同步的,並且當合適時可以返回 Promise。(在某些情況下,例如事件監聽器(例如:chrome.tabs.onRemoved),返回 Promise 是不合理的)。然而,讀取回應可以使用回調或 Promise 風格來完成。

內容腳本:讀取回應的方法 1:

chrome.runtime.sendMessage('ping', (response) => { /* read response */ })

內容腳本:讀取回應的方法 2:

chrome.runtime.sendMessage('ping').then(response => { /* read response */ })

你所面臨的問題是:背景腳本對其收到的一個或多個訊息沒有調用 sendResponse(),並且變為非活動狀態(導致訊息通道關閉)。然而,發送訊息的內容腳本正在等待回應。

請檢查您的訊息發送者和處理者。

答案#4

這已經在 webextension-polyfill 庫中被討論過,該庫被許多擴充功能使用(包括 Ghostery)。最近 Chrome 有一個更改,引入了這個錯誤訊息。

對於使用 polyfill 的專案,我預計如果修正被合併,警告將會消失。請注意使用 polyfill 函式庫的原因是,只有 Firefox 實作了新的基於 Promise 的 runtime.onMessage,而 Chrome 仍然強制使用原本的回呼式 API。

請注意,webextension-polyfill 庫中已經有一個開放的拉取請求。它尚未被合併,但根據我的測試,它已經解決了這個問題。因此,如果你需要對一個內部使用該庫的專案進行快速修復,你可以使用 patch-package 手動應用這個補丁。例如,在 Ghostery 中,這樣的更改會是這樣的。

答案#5

此錯誤與廣告攔截器或類似的應用有關。只需將此應用程式排除在該網站之外。在我的情況下,是 AdBlock 應用程式。當使用 LiveServer 或 FiveServer 時,它一直在控制台中顯示此錯誤。這不影響任何功能,但非常惱人