LoginSignup
2
3

More than 3 years have passed since last update.

リンクをブラウザ機能で開いた場合window.openerはnullになる

Posted at

代案はlocalStorageWebSocket・強制を検討。

一応の結論

同一オリジンならlocalStoragewindow.postMessage代わりに使うのがお手軽。
おそらく個人開発規模で複数ドメインを手がけることも少ないと思われるので、一旦最有力としておきます。

扱わないこと

target="_blank"は危険だよ!
というnoopener周りの話

リンクを作る時の target="_blank" の危険性 - 隙あらば寝る

まとめ

自分の管理下にあるサイトであればリスクはかなり低いと思われる。

一方で外部へのリンクをtarget="_blank" で作成している場合は対策を行っておいたほうが良い。
(後略)

あらまし

<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要素を使っても左クリック以外をイベントでキャンセルしちゃえば。なつかしの右クリック禁止ですね。

それらをかいくぐるならもう多少の不都合はユーザーの責任ですし。

問題はそれらの手法がとても私の好みではないということと、
利用者=自分なのでただただ自分が不便になるだけという悲しみ。

2
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
3