代案はlocalStorage
・WebSocket
・強制を検討。
一応の結論
同一オリジンならlocalStorage
をwindow.postMessage
代わりに使うのがお手軽。
おそらく個人開発規模で複数ドメインを手がけることも少ないと思われるので、一旦最有力としておきます。
扱わないこと
target="_blank"
は危険だよ!
というnoopener
周りの話
リンクを作る時の target="_blank" の危険性 - 隙あらば寝る
まとめ
自分の管理下にあるサイトであればリスクはかなり低いと思われる。
一方で外部へのリンクをtarget="_blank" で作成している場合は対策を行っておいたほうが良い。
(後略)
- target="_blank"には気をつけよう - Qiita
- target="_blank" で開くリンクには rel="noopener" をつける - Qiita
- Firefox security: rel=noopener for target=_blank - gHacks Tech News
あらまし
<a target="_blank">
(やwindow.open
)
なクリックすることで別タブ(window)で開くリンク先でwindow.opener
を使ったリンク元との通信・連携を記述していた。
しかし、マウスの中央ボタンクリックや右クリックメニューのリンクを新しいタブで開く
によるopenではwindow.opener
がnullになってしまう。
window.opener
に依存しない連携の必要を検討しなければならなかった。
もともと使おうとしていた機能はwindow.postMessage
なのでクロスオリジンにも一応留意する。
右クリックはともかくバックエンドでタブを開く中央ボタンクリックは<a target="_blank">
の有無関係なしに多用する機能なので、左クリックを強制されると使用感が損なわれる。※個人の感想です‘
という検討を机上の空論で行います。
環境
Firefox 68.0.1
二つの代案の共通問題点
以下に書く代案での問題として、ページ間の親子関係がないことがあげられる。
window.opener
がnullだからしかたないのだが、親ページを複数開いていた場合にはリンクをクリックした親ページ以外の各ページで反応してしまうと思われる。
(ページごとにランダム生成したユニークな値をリンク先のgetパラメーターに含めるとか無理やりな考えもできないくもなさそうだけど捨て置く)
あくまで
親ページは子ページを開く役割を自覚している。
子ページも親ページから開かれることを自覚している。
という前提でスクリプトを書く。
だからどちらかといえば一般的なページではなくローカルな自作HTMLやユーザースクリプトとして書いている場合の話です。
(ついでにiframeを使った力業も考慮しません。)
localStorage
を使う
window.postMessage
によるイベント駆動の代案としてlocalStorage
が考えられる。
Web Storage API を使用する - Web API | MDN
localStorage
にはStorageEvent
が用意されているので、子ページでStorageに書き込むことでメッセージ送信かのように扱うことができる。
localStorage
を使った似たような問題解決の手法として
localStorage
をポーリングで監視する手法が紹介されていたが、
window.openerがiOS版Chromeで使えない問題に対処するには?
一瞥したかぎりではイベントのほうがよさそうに思える。
実際に組んだことがないので実用上の問題があるのか、記事が2016年のものなので機能がなかったのかは不明。
問題点
ゴミが残る。
localStorage
はデータ永続用のStorageなので通信用の使い終わった値が掃除しない限りは残ってしまう。
もちろんStorage.removeItem()
は用意されているので変更を検知したらつど削除でもよい。
永続として不要なデータが残るor毎回掃除している
ということが感覚的に気持ち悪い場合は採用しにくいか?
なお、自動的に削除されるsessionStorage
には変更イベントは用意されていない。ページ(session)単位のStorageなので致し方ない。
クロスオリジンできない
Web Storage APIはあくまでドメインごとのStorageを提供する機能なので別ドメインでのStorage操作を検知することはできない。
window.postMessage
は安全にクロスドメイン通信を可能にすることがウリのひとつなので、そのために使っていた場合は代案になりえない。
WebSocket
を使う
君なんでもWebSocket
使うよね
まーまー通信という意味ではお手軽です。
双方向通信機能を使ってやりとりが出来ない理由がないです。
同様にクロスオリジンの問題もなし。
問題点
WebSocket
そのものの話ですが
サーバーが必要
なのだが、個人利用では
手元にサーバー不要でWebSocket Client間で通信できるフリーサーバー Achex, Websocket.in が便利そう - Qiita
で回避するのでまあまあ。
あとページがセキュアならそこも面倒に。片方だけhttpsで引っかかるなんてことも万が一あるかも。
FirefoxでhttpsからWebSocket接続(ws)するにはnetwork.websocket.allowInsecureFromHTTPS - Qiita
接続管理が必要
信頼性は体感高いものの、絶対connectionできる、接続が維持され続けるといえるものではないのである程度管理用にコード量が増加すると思われる。
これも個人利用ならまあ杜撰でも許容範囲ですが。
左クリックを強制させる
window.opener
を担保したい方向。
ユーザーに不便を押し付ける形に。
a
要素を使わずにすべてクリックイベントでwindow.open
にされたら一般ユーザーにはなかなか手出しは難しいと思います。
a
要素を使っても左クリック以外をイベントでキャンセルしちゃえば。なつかしの右クリック禁止ですね。
それらをかいくぐるならもう多少の不都合はユーザーの責任ですし。
問題はそれらの手法がとても私の好みではないということと、
利用者=自分なのでただただ自分が不便になるだけという悲しみ。