iframeのクロスドメイン対応と要素取得手法

  1. 要件としてiframeによるページ埋め込みを実現し、スクロールバーを非表示にすることで、二つのページが連結されたような効果を得る

  2. クロスドメイン問題の対処には、プロキシ設定を利用

  proxy: {
    '/medical': {
      target: 'https://example.com',
      changeOrigin: true,
      pathRewrite: {
        '^/medical': '',
      },
    },
  }

  1. iframeの幅を取得し、スクロールバーの出現を防ぐための幅調整を行う
  <iframe
        ref="iframe"
        name="sonFrame"
        class="iframe hide-in-large hide-in-medium"
        width="100%"
        :height="height"
        marginWith="0"
        scrolling="no"
        src="/medical/example...."
        frameborder="0"
      ></iframe>

    this.iframe = this.$refs.iframe;
      // iframe読み込み完了後に高さを調整
      this.iframe.onload = () => {
        this.height = this.iframe.contentDocument.body.scrollHeight;
      };

主な課題はクロスドメインによりiframe内の要素にアクセスできず、結果的に高さの算出が困難になること

++++++++++++++++++++++++++++++++++++++++++++++++++ 4. 新たな問題点

  • モバイル端末でのみiframeを表示し、他の画面ではスタイルで非表示にする方式を採用。横画面時に非モバイル端末でもPCスタイルが適用され、文字サイズが拡大されるが、横画面から縦画面に戻った際には元のフォントサイズに戻らない
  • 対策:
    1. v-ifを使用して再レンダリングを行う => デメリット:ネットワークリクエストが繰り返される
    1. v-showで要素の可視性を切り替える => メリット:再リクエストなし。ただしPC環境でもDOMが生成される。この方法が成功する理由は、PC画面時のiframeが描画されていない状態ではレスポンシブな文字サイズ変更が発生しないため

+++++++++++++++++++++++++++++++++++++++++++++++++++

5. WeChatブラウザ/QQブラウザにおける画面回転時のフォントサイズ異常

WeChatおよびQQブラウザではresizeイベント発生直後のinnerWidth値が横画面後の値ではなく、遅延して取得する必要がある。そのためiframeを再読み込みする必要がある この場合v-showは使用不可。resize時に即座にiframeを非表示にしても、既に横画面用のフォントサイズに変更されているため

  • 実装コード
    <div class="mt-40">
      <!-- WeChat/QQブラウザではiframeを再ロードする必要あり -->
      <iframe
        v-if="!isPc && isWeiXin"
        width="100%"
        marginWith="0"
        scrolling="no"
        src="/medical/ecp-cms/cdn-file/tac/content/WMS/0/TAC_MEDICAL.html"
        frameborder="0"
      ></iframe>
      <!-- その他のブラウザでは再レンダリング不要 -->
      <iframe
        v-show="!isPc && !isWeiXin"
        width="100%"
        marginWith="0"
        scrolling="no"
        src="example.html"
        frameborder="0"
      ></iframe>



  computed: {
    // WeChatブラウザまたはQQブラウザかどうか判定
    isWeiXin() {
      const ua = navigator.userAgent.toLocaleLowerCase();
      return (
        window.navigator.userAgent.includes('MicroMessenger') ||
        ua.match(/tencenttraveler/) != null ||
        ua.match(/qqbrowse/) != null
      );
    },
  },

   window.addEventListener('resize', () => {
        // WeChat/QQブラウザではresize直後のinnerWidthは更新後の値ではないため、遅延して取得
        const delay = this.isWeiXin ? 100 : 0;
        setTimeout(() => {
          this.isPc = window.innerWidth > 719;
        }, delay);
      });

タグ: iframe cross-domain vue.js proxy resize

5月21日 01:41 投稿