html5 postMessageのフロントエンドクロスドメインとフロントエンドのリスニング方式の例
時には、フロントエンドでシングルサインオンをしろ!などという馬鹿げた要求もあります。要件を受けたら、解決策を考えなければなりません。
ここで、簡単なフロントエンドのシングルサインオンソリューションを作ってみましょう。
postMessageのクロスドメインメッセージングとonstorageのリスニングを使用しています。
この記事で使用した知識: KOA 静的リソースサービスの設定、クロスドメイン、postMessage の使用法、onstorage のストレージへのリスニング
最初のステップは、2つの異なるポートでサービスをセットアップすることです。
ここではkoa2を使って、実際の業務で発生する必要のあるクロスドメインの状況をシミュレートするために、異なるポートに2つのサービスを構築しています。
とてもシンプルですね。主にkoa-staticというミドルウェアを使っています。
もしあなたがノード関連の知識を学びたいなら、私のWeChat shouzi_1994を追加するか、ブログの下にあなたの連絡先を残してください。
// localhost:4000
const Koa = require('koa');
const path = require('path')
const static = require('koa-static')
const app = new Koa();
// Set the path to the static resource
const staticPath = '. /static'
app.use(static(
path.join( __dirname, staticPath)
))
console.log("Service started on port 4000")
app.listen(4000);
// localhost:3000
const Koa = require('koa');
const path = require('path')
const static = require('koa-static')
const app = new Koa();
// Set the path to the static resource
const staticPath = '. /static'
app.use(static(
path.join( __dirname, staticPath)
))
console.log("Service started on port 4000")
app.listen(4000);
ステップ2、クロスドメインコミュニケーション postMessage
まず、postMessageのAPIを見てみましょう。
otherWindow.postMessage(message, targetOrigin, [transfer]);
他のウィンドウ
iframe の contentWindow プロパティ、window.open の実行により返されるウィンドウ オブジェクト、名前付きまたは数値インデックス付きの window.frames などの、別のウィンドウへの参照です。
メッセージ
他のウィンドウに送信するデータです。構造化クローンアルゴリズムによってシリアライズされる。つまり、データオブジェクトを自分でシリアライズすることなく、何の制限もなく安全にターゲットウィンドウに送信することができます。[1]
ターゲットオリジン
その値は文字列 "" (無制限の場合) または URI のいずれかです。メッセージを送信するとき、ターゲットウィンドウのプロトコル、ホストアドレス、ポートの 3 つのうち 1 つでも targetOrigin で指定した値に一致しない場合、メッセージは送信されません。3つすべてが正確に一致した場合のみ、メッセージは送信される。例えば、postMessage でパスワードを送信する場合、悪意のある第三者に傍受されないように、このパラメータの値が、パスワードを含むメッセージの受信予定者の origin 属性と正確に一致することが特に重要なのです。もしどのウィンドウにメッセージを送るべきか正確に知っているのであれば、代わりに必ず正確な値を targetOrigin に指定してください。正確なターゲットを指定しないと、そのデータに興味を持つ悪意のあるサイトにデータが漏えいすることになります。
転送 オプション
は、メッセージとともに渡される転送可能なオブジェクトの文字列です。これらのオブジェクトの所有権はメッセージの受信者に移り、送信者は所有権を保持しなくなる。
どうです、わかりやすいでしょう!ここでちょっとだけ文化を紹介しましょう。
転送先の(親)子ウィンドウ。postMessage(何を転送するか、どのアドレスに転送するか、[パーミッションを転送するかどうか(通常は使用しません)])。
あらかじめ、ドメインをまたいで転送するためには、親子ページ、つまりjsで開くページ、ifreamでネストされたページであることが必要です
では、コードを書き始めましょう
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head>
<body>
<! -- postMessage and iframe solve common cross-domain problems -->
I am the content of the port 3000 site
<button onclick="send()">Send message to son</button>
<iframe style="display:none" src="http://localhost:4000" frameborder="0"></iframe>
<script>
function send() {
window.frames[0].postMessage({a:"1"},"http://localhost:4000"); // trigger the message-event for the cross-domain subpage
}
window.addEventListener('message', function(event) {
console.info('A letter from my son', event);
}, false);
</script>
</body>
</html>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head>
<body>
<! -- postMessage and iframe solve common cross-domain problems -->
I am the content of the port 4000 site
<button onclick="send()">Send message to dad</button>
<iframe style="display:none" src="http://localhost:4000" frameborder="0"></iframe>
<script>
window.addEventListener("message",function(event){
console.log("A letter from dad: ", event)
},false)
function send() {
parent.postMessage({a:1}, 'http://localhost:3000'); //
}
</script>
</body>
</html>
この時点で、親ページと子ページの間のクロスドメイン通信を実装しましたが、この通信はウィンドウ内でしか行われず、私が望むような効果は得られないので、どうすればよいでしょうか。
値の変化をリスニングし、時間内に反応する
この時点までに、同じドメインのすべてのサイトが、ブラウザ上で何が見えるかを考える必要があります。
そうだ、ストレージだ!これを聞けばいいんだ。
ここでは、loacalStorageをリッスンすることを選択します。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head>
<body>
<! -- postMessage and iframe solve common cross-domain problems -->
I am the content of the port 4000 site
<button onclick="send()">Send message to dad</button>
<iframe style="display:none" src="http://localhost:4000" frameborder="0"></iframe>
<script>
window.addEventListener("message",function(event){
console.log("A letter from Dad: ", event)
var data = JSON.stringify(event.data)
window.localStorage.setItem("data",data)
},false)
window.onstorage(function(st){
console.log(st.key,st.value)
})
function send() {
parent.postMessage({a:1}, 'http://localhost:3000'); //
}
</script>
</body>
</html>
ほら、もうクロスドメイン転送に対応できるようになったでしょ?
について考える
2ページ分のクロスドメインコミュニケーションができたので、3ページから多数へのクロスドメインコミュニケーションはどうすればいいのでしょうか?それは、理にかなっています。根拠を示したので、実際に書いて体験してみてください。
この記事がお役に立てれば幸いです。そして、スクリプトハウスを応援していただければと思います。
関連
-
モバイルHTML5開発ツール vconsoleの詳細解説
-
HTML5入門(II)
-
html5 on outbound embedded page 通信問題 (postMessage でクロスドメイン通信を解決)
-
iframeタグが入れ子になっている問題の解決法
-
postMessageを用いたiframeのクロスドメイン通信問題の詳細な解決法
-
SVG描画をHTMLページに持ってくる実装
-
HTML5 における scroll-to-bottom イベントの問題を解決する方法
-
HTML5でWeb Notificationのデスクトップ通知を実装する方法
-
異なるiosデバイスでのh5ページの詳細 問題点まとめ
-
html5のfigureとfigcaptionの使い方
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
キャンバス描画の解像度が拡大され、ぼやけた状態になる
-
高解像度画面でのキャンバスブラーの問題を記憶する
-
アップロード用画像の圧縮にcanvasを使用した例
-
タオバオH5サイン暗号化アルゴリズムの詳細
-
Canvasを使用したHD画面での描画がにじむ問題とその解決方法について
-
HTML5タイマーrequestAnimationFrameの使い方を深く理解する。
-
モバイル開発 HTML5 ボタンをクリックすると、ページがちらついたり、背景が黒くなったりする問題
-
Html5キャンバスパーティクルクロック サンプルコード
-
5分でわかるHTML5 WebSocketプロトコル
-
webViewでhtml画像を読み込む際の問題を解決する。