2013-12-13 30 views
0

crossrider sidepanel只是一個iframe(您可以使用js注入html,但我有興趣使用iframe來減少對頁面其餘部分的干擾)。我無法在瀏覽器擴展和iframe之間進行任何交互。與crossrider sidepanel插件通信

除非你可以做一些基本的JS通信,否則在添加一個帶有擴展的sidepanel時我完全沒有意識到。在這種情況下,我想在控制擴展的iframe中使用幾個選項,複選框等。由於這個插件存在,我假設必須有一種方法。

理想情況下,我想在子iframe中有一些基本的輸入處理js,並讓它發送奇怪的保存/加載命令。答案真的是某種形式的消息傳遞?如果是的話,我應該在這裏使用哪個API?

我相信這是有關:Accessing iframe from chrome extension

[編輯]
好了,我已經嘗試了一些東西......

  1. 似乎預期的使用是舉辦iframe的html內容。有點奇怪,考慮到它應該是本地和擴展的一部分。如果你想離線查看一些頁面會發生什麼?這只是愚蠢的,我把它作爲一個選項予以解僱。爲什麼要浪費資源來託管應該在當地可用的東西。

  2. 另一種方法是提供進入側邊欄的HTML。請注意,此HTML不會放入iframe中。我喜歡iframe的想法,因爲它使CSS和JS保持獨立,所以頁面和擴展之間的干擾最小。

    所以我嘗試通過html側欄屬性與ID創建iframe,並在使用myiframe.contentWindow.document.open/writeln/close()延遲100ms後注入了內容。這工作正常鉻,但失敗的Firefox與安全錯誤(The operation is insecureopen())。

  3. 另一種方法是通過src url(對於邊欄我使用url屬性的數據地址)提供iframe內容:Html code as IFRAME source rather than a URL。這在Firefox,但導致CORS錯誤在Chrome:The frame requesting access has a protocol of "http", the frame being accessed has a protocol of "data". Protocols must match.Warning: Blocked a frame with origin "http://localhost" from accessing a cross-origin frame. Function-name: appAPI.message.addListener

這些CORS問題罷工我真的很愚蠢。這是我的所有代碼都來自同一個擴展,注入同一頁面。沒有交叉的起源發生,我創造了該死的東西。如果我有權力改變起源,那麼它首先是不安全的,所以爲什麼要這麼做。

回答

2

假設你正在使用的網址欄屬性加載側邊欄的HTML(即託管的網頁),您可以使用分機中的iFrame功能運行iframe的延伸和父窗口的擴展名之間進行通信。

要做到這一點,首先啓用擴展到iframe中運行(設置在I幀>運行),然後你可以使用extension.js加載你的側邊欄和處理消息。例如,下面的代碼加載具有與識別按鈕btnSave一頁:

託管網頁文件:

<html> 
<head> 
</head> 
<body> 
    <div id="mySidebar"> 
    My sidebar form 
    <br /> 
    <button id="btnSave">Save</button> 
    </div> 
</body> 
</html> 

extension.js文件:

appAPI.ready(function($) { 
    // Check if running in iframe and the sidebar page loaded 
    if (appAPI.dom.isIframe() && $('#mySidebar').length) { 
    // Set click handler for button to send message to parent window 
    $('#btnSave').click(function() { 
     appAPI.message.toCurrentTabWindow({ 
     type:'save', 
     data:'My save data' 
     }); 
    }); 
    // End of Iframe code ... exit 
    return; 
    } 

    // Parent window message listener 
    appAPI.message.addListener(function(msg) { 
    if (msg.type === 'save') { 
     console.log('Extn:: Parent received data: ' + 
     appAPI.JSON.stringify(msg.data)); 
    } 
    }); 

    // Create the sidebar 
    var sidebar = new appAPI.sidebar({ 
    position:'right', 
    url: 'http://yourdomain.com/sidebar_page.html', 
    title:{ 
     content:'Sidebar Title', 
     close:true 
    }, 
    opacity:1.0, 
    width:'300px', 
    height:'650px', 
    preloader:true, 
    sticky:true, 
    slide:150, 
    openAction:['click', 'mouseover'], 
    closeAction:'click', 
    theme:'default', 
    scrollbars:false, 
    openOnInstall:true, 
    events:{ 
     onShow:function() { 
     console.log("Extn:: Show sidebar event triggered"); 
     }, 
     onHide:function() { 
     console.log("Extn:: Hide sidebar event triggered"); 
     } 
    } 
    }); 
}); 

但是,如果您使用側欄屬性加載您的sideba r的HTML,那麼這個解決方案將不起作用,因爲擴展不會在這種情況下運行。但是,您可能能夠利用您引用的StackOverflow線程中描述的方法與父窗口進行通信(這將是瀏覽器特定的),這些方法又可以使用我們的CrossriderAPI event與擴展進行通信。

[免責聲明:我是一個Crossrider員工]

+0

非常感謝!有沒有一種方法可以將'url'參數指向本地文件,例如crossrider'resources'目錄中的文件?目前我通過'html'參數創建iframe,並手動注入'resources' html文件。我希望擴展程序在本地運行,而不需要服務器。 – jozxyqk

+0

它看起來像注入將無法使用運行在iframe選項 - *「請注意,在Chrome中只有現有的iframes適用」*。有沒有一種方法可以明確要求API將自己注入給定的iframe中? – jozxyqk

+0

在當前的實現中,只能在頁面託管並使用URL屬性的情況下才能在Iframe中運行。如答案中所述,使用HTML屬性,您可以使用本機瀏覽器特定的消息傳遞在iframe和父頁面之間進行通信。 – Shlomo