Chrome拡張機能で、options.html
ページをGoogleのOpenIdAPIなどと通信させたいです。これをシームレスに行うために、オプションページにiframe
を非表示にして、Googleアカウントのログインページをポップアップします(OpenIdインタラクションシーケンスなどに従います)。
私の問題は、オプションページからiframe
に通信できないことです(iframe
の原点は私が制御するものですが、私のchromeと同じではありません拡張)window.postMessage
経由。この問題の迅速な回避策があるかどうか疑問に思っていました。
ない場合は、options.html
にページのレイアウトとロジックを格納するiframe
を含めるようにします。
Iframeをいじる必要はありません。バックグラウンドページを使用して、クロスドメインXMLHttpRequestsを実行することが可能です。 Chrome 13なので、コンテンツスクリプトからクロスサイトリクエストを行うことができます。ただし、ページに制限付きのコンテンツセキュリティポリシーヘッダーが提供されている場合、リクエストは失敗する可能性があります connect-src
。
コンテンツスクリプトではなくnexyメソッドを選択する別の理由は、httpサイトへのリクエストにより、混合コンテンツの警告が発生することです(「https:// ...のページにhttp:// ...の安全でないコンテンツが表示されました」)。
リクエストをバックグラウンドページに委任するもう1つの理由は、file://
スキームのページで実行されていない限り、コンテンツスクリプトをfile:
から読み取ることができないため、file://
からリソースを取得する場合です。
注
クロスオリジンリクエストを有効にするには、マニフェストファイルのpermissions
配列を使用して、拡張機能に権限を明示的に付与する必要があります。
コンテンツスクリプトは messaging APIを介してバックグラウンドから機能をリクエストします。これは、リクエストの応答を送受信する非常に簡単な方法の例です。
chrome.runtime.sendMessage({
method: 'POST',
action: 'xhttp',
url: 'http://www.stackoverflow.com/search',
data: 'q=something'
}, function(responseText) {
alert(responseText);
/*Callback function to deal with the response*/
});
/**
* Possible parameters for request:
* action: "xhttp" for a cross-Origin HTTP request
* method: Default "GET"
* url : required, but not validated
* data : data to send in a POST request
*
* The callback function is called upon completion of the request */
chrome.runtime.onMessage.addListener(function(request, sender, callback) {
if (request.action == "xhttp") {
var xhttp = new XMLHttpRequest();
var method = request.method ? request.method.toUpperCase() : 'GET';
xhttp.onload = function() {
callback(xhttp.responseText);
};
xhttp.onerror = function() {
// Do whatever you want on error. Don't forget to invoke the
// callback to clean up the communication port.
callback();
};
xhttp.open(method, request.url, true);
if (method == 'POST') {
xhttp.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
}
xhttp.send(request.data);
return true; // prevents the callback from being called too early on return
}
});
備考:メッセージングAPIは何度か名前が変更されました。ターゲットブラウザが最新ではない場合Chromeバージョン、チェックアウト この回答 。
完全を期すために、ここに私のデモを試すための マニフェスト ファイルがあります:
{
"name": "X-domain test",
"manifest_version": 2,
"permissions": [
"http://www.stackoverflow.com/search*"
],
"content_scripts": {
"js": ["contentscript.js"],
"matches": ["http://www.example.com/*"]
},
"background": {
"scripts": ["background.js"],
"persistent": false
}
}
私はjqueryを使用して同じことを実装しましたが、はるかに単純で、うまくいきました。
background.js
chrome.runtime.onMessage.addListener(function(request, sender, callback) {
if (request.action == "xhttp") {
$.ajax({
type: request.method,
url: request.url,
data: request.data,
success: function(responseText){
callback(responseText);
},
error: function(XMLHttpRequest, textStatus, errorThrown) {
//if required, do some error handling
callback();
}
});
return true; // prevents the callback from being called too early on return
}
});
contentscript.js
chrome.runtime.sendMessage({
method: 'POST',
action: 'xhttp',
url: 'http://example-url.com/page.php',
data: "key=value"
}, function(reponseText) {
alert(responseText);
});
しかし、manifest.jsonファイルに必要な権限とjquery jsファイルがあることを確認してください
"permissions": [
"tabs", "activeTab", "http://example-url.com/*"
],
"content_scripts": [ {
"js": [ "jquery-3.1.0.min.js", "contentscript.js" ],
"matches": [ "https://example-ssl-site.com/*" ]
}],
"background": {
"scripts": [ "jquery-3.1.0.min.js", "background.js" ]
}