文系プログラマによるTIPSブログ

文系プログラマ脳の私が開発現場で学んだ事やプログラミングのTIPSをまとめています。

【iframe】クロスドメインを無視して別ドメインのhtmlを取り込む【jsp】

強引ですが、力技で実現できたりします〜


f:id:treeapps:20180426142529p:plain

自分のサイトに別ドメインのサイトを取り込む時、iframeが一般的にですね。

しかしこのiframe、heightとwidthが動的に変わらず、固定値になってしまう問題があります。

この縦横固定を解消するため、iframe内のhtmlの描画完了後、html全体の縦横を取得し、javascriptでiframeのheightとwidthを動的に指定する手法が有ります。

しかしこの手法、クロスドメイン下ではDOMに触れないという制限があるせいで、iframe内をjavascriptで触る事すらできません。つまり縦横が取得できません。

それを解消する方法として、window. postMessageを利用する方法があります。親・子それぞれにpostMessageを埋め込み、親子でメッセージの送受信をします。これは親・子それぞれ別のjavascriptを仕込む事で実現できますが、IE8以降でしか動きません。

これに対処するため、location.hashを使って、URLにメッセージを埋め込んで、それをリスナーで監視して子から親へのメッセージ送信を実現する方法もあります。

この2重の施策でようやく全ブラウザでiframe内の縦横幅を取得できます。

・・・

・・・・・・

これ、大変過ぎじゃない?


たかが縦横取得するのにここまでしないといかんのか?と疑問に思ってました。
そこで私はjspで全く別の方法で対応する方法を考えました。

jstlを使うと別ドメインのURLを取り込める

はい。JSTLの<c:import>を使うと、別ドメインのhtmlをjspに取り込めちゃうんです。

<html>
<body>
<c:import url="http://www.google.co.jp" encoding="UTF-8" />
</body>
</html>

こう書くと、jspの中にurlで指定したhtmlをそのまま取り込めるのです。

しかし注意点が2点あります。

1点目は、html全体が取り込まれるので、取り込み先サイトにhtmlやbodyタグを書いてはいけません。完全にパーツ部分だけのhtmlにする必要があります。

そうしないと、↓こうなります。

<html>
<body>
<html>
<body>
ggrks
</body>
</html>
</body>
</html>

htmlの中にhtmlが描画され、htmlが崩れます。

2点目は、相対パスは取り込み元から見た相対パスになってしまう点です。例えば取り込み先のhtmlが以下であったとします。

<html>
<body>
<img src="/images/hoge.jpg">
</body>
</html>

取り込み元jspでc:importしてこのhtmlを取り込むと、取り込み元から見た相対パスとして判断され、取り込み元にはそんな画像は無いので404になります。

iframeは取り込み先を基準に相対パスが処理されるのに対し、c:importは取り込み元が基準になります。取り込み先にしかないファイルを使用する場合は絶対URL(http://xxx/hoge.jpg等)を書き、取り込み元の画像を利用したい場合は相対URLで書く、という使い分けが必要になります。

この手法はiframeやincludeというより、htmlを返すapiを使っているイメージですね。

メリット

  • クロスドメインを気にせずhtmlを取り込め、高さも幅も自動調節できる。(純粋なhtmlとして処理されるため)
  • 取り込み先にcssや画像を置かなくてもよくなる。
  • 取り込み先はパーツ部分のhtmlしか書かなくてよくなる。(htmlの編集ミスを減らせる)
  • 実装が単純なので、javascriptが苦手な人でも簡単に実装・メンテできる。
  • 全ての処理を取り込み元で行うので、取り込み元のjsで取り込み先のdomに余裕でアクセスできる。

デメリット

  • 取り込み先でhtmlを確認できない。(html全体ではなくパーツしか記述しないため)
  • 相手の協力が無いとそもそも成り立たない。

まとめ

相手の協力が無いと成り立たない小技ではありますが、クロスドメインを無視して処理できちゃうので、クロスドメインiframeに対応する時間が無い場合等で使えるかも???しれません。