2

IE、FF、Safari、および Chrome で正常に動作する、glassfish 3.1 で実行されている JSF 2.0 Web アプリケーションがあります。

別の Web サイトの iframe 内に自分の Web サイトの URL を追加すると、iframe 内の任意のボタンをクリックすると ViewExpiredException が発生します - これは Safari でのみ発生し、IE、FF、Chrome で正常に動作します。

<iframe style="width: 100%; height: 800px" src="url_of_my_website" frameBorder="0"></iframe>

以下は私の観察です

  1. 同じアプリケーションを Glassfish 3.0.1 にデプロイしましたが、問題は発生しません
  2. フレームなしでウェブサイトを開くと、ブラウザに関係なく正常に動作します
  3. JSF1.2 と RF 3.3.3 を使用して同じアプリケーションを開発しましたが、問題は発生しません。

私の理解によると、セッションが期限切れになっているページでアクションが実行されると、 ViewExpiredException が発生します。ただし、この特定のケースでは、Web サイトがロードされた直後に発生します。

何が原因なのかわかりません。Safari/JSF 2.0/GF 3.1/IFRAME ですか?

更新: 興味深い問題が見つかりました。私のホームページには、新しいページにリダイレクトする ah:commandLink があります。また、他のページにリダイレクトするための href リンクがあります。commandLink をクリックすると ViewExpiredException が発生しますが、href リンクをクリックすると例外が発生せず、ページがリダイレクトされ、セッション Cookie が確立されているため、さらに操作を続行できます。

4

2 に答える 2

3

これは既知の問題です。Safari はクロスドメイン Cookie を許可しません。iframe によって配信されるすべての Cookie は、このブラウザーによって無視されます。HTTP セッションは Cookie によってサポートされています。したがって、それは同様に維持されません。したがって、iframe 内で JSF フォームを送信すると、Safari はセッション Cookie を返送せず、サーバー側が暗黙的に新しいセッションを作成するため、最初のセッションで設定されたビューは完全に失われます。したがって、ViewExpiredException.

理論的には、これは、JSF によって生成された HTML要素JSESSIONIDの URL にフラグメントを含めることで解決できます。例えばaction<form>

<form action="/context/page.xhtml;JSESSIONID=1234567890ABCDEF">

しかし、JSF はすでにそれを行っています。そのためにカバーの下で使用しHttpServletResponse#encodeURL()ます。JSF 1.2 では機能しているように見えたのに、JSF 2 では機能しなかったということは、私にとって謎です。しかし、あなたは今、少なくとも集中すべき何かを持っています。内部HttpServletResponse#encodeURL()で適切にエンコードされた URL を返しましたか? JSESSIONID生成された HTML<form>にはJSESSIONID? などなど、Mojarraを利用する場合はFormRenderer#getActionStr()、デバッグしながらメソッドから始めます。

とにかく、別の解決策は、これに JavaScript を使用することです。iframe 内に表示される JSF ページのオンロード中に、次のようなことを行います。次のスクリプト キックオフの例は、#{}評価されるように JSF ページ内に埋め込む必要があります。

window.onload = function() {
    if (top != self) { // If true, then page is been requested inside an iframe.
        var jsessionid = '#{session.id}';
        var forms = document.forms;

        for (var i = 0; i < forms.length; i++) {
            forms[i].action += ';JSESSIONID=' + jsessionid;
        }
    }
}

これは、Safari 以外のブラウザーに害を及ぼすことはありません

于 2011-08-12T16:23:08.770 に答える
0

IE と Safari で同じ問題が発生しました。これは、これらのブラウザではサード パーティの Cookie がデフォルトで許可されていないためです。したがって、セッション ID を Cookie 経由で渡すことができませんでした。

IE でこれを修正するには、値 CP="This site does not have a p3p policy." を含む応答ヘッダー P3P を追加するだけで十分です。

ExternalContext extContext = FacesContext.getCurrentInstance().getExternalContext();
extContext.addResponseHeader("P3P", "CP=\"This site does not have a p3p policy.\"");

Safari で修正するには、セッション ID を URL で転送しますが、Cookie では転送しません。これは、URL の書き換えとして知られています。Servlet 3.0 をサポートするアプリケーション サーバーの場合は、 web.xml を使用して実行できます。

<session-config>
    <tracking-mode>URL</tracking-mode> 
</session-config>
于 2016-05-24T12:41:49.153 に答える