12

私たちのチームは最近、ある種の JavaScript レンダリング (Ajax、タブなど) を持つページからブラウザーの戻るボタンをクリックすると、未加工の JavaScript がユーザーに表示されるという最初のエッジケースの問題を提示されました。再作成するには、次の手順に従いました。

  • ユーザーの求人応募インデックスにアクセスする
  • ボタンをクリックすると、求人掲載の管理ページに移動します
  • タブをクリックします (bettertabs gem を使用)
  • ブラウザの戻るボタンをクリック

前の手順では、次のように表示されます。

(function() {

  $(".job_applications").html("<li class=\"job_posting_application\">\n
    ...
    ...
    ...
    ...
  );

}).call(this);

場合によっては、前のページに戻る前にタブをクリックする必要はありませんが、それでも未加工の JavaScript がレンダリングされます。結局のところ、最後にレンダリングされたテンプレートがキャッシュされているように見えます。これは正常であり、ブラウザー側で予期されていることですが、より大きな問題であると私が信じていることにつながります。

Rails Guides のLayouts and Renderingのセクションで、特にテンプレートの MIME タイプに関して次のように述べています。

デフォルトでは、Rails は text/html (または :json オプションを使用する場合は application/json 、または :xml オプションを使用する場合は application/xml ) の MIME コンテンツ タイプでレンダリング操作の結果を提供します。

Rails のデフォルトに基づいて、コントローラーの index アクションがindex.html.slimテンプレートをレンダリングすることが期待されます。ただし、サーバー ログの追跡中にそのページへの非リモート呼び出し (たとえば、ブラウザーでページに直接移動する) を行うと、実際にレンダリングされることがわかりますindex.js.coffee。以下はコントローラー アクションです。html または js 形式に明示的に対応していないことに注意してください。

def index
  @company_id, @division_id, @job_posting_id = params[:company_id], params[:division_id], params[:job_posting_id]

  # API requests are made here to instantiate @job_posting, et al.,
  # but are not shown for brevity

  authorize! :manage, @job_posting

  @survey = @job_posting.survey
  @job_applications = @job_posting.job_applications(sort_column, sort_direction)
end

ただし、この設定では、Rails のデフォルトに基づいてレンダリングするindex.html.slim 必要があります。ブロックを追加するときrespond_to、キャッシュがまだ有効であるように見え、コントローラーはブロックの存在をあまり気にしませんrespond_to:

def index
  ...
  ...
  respond_to do |format|
    format.html
    format.js
  end
end

たとえ臭くても、明示的に各フォーマットに異なるテンプレートをレンダリングするように指示したとしても、js.coffeeテンプレートがテンプレートよりも優先されるようですhtml.slim:

def index
  ...
  ...
  respond_to do |format|
    format.html { render template: "users/job_posting_applications/index" }
    format.js { render template: "users/job_posting_applications/ajax" }
  end
end

上記の場合、ブラウザーでページに直接移動する (つまり、リモート Ajax 呼び出しを行わない) と、ajax.js.coffee特に指定がない限り、Rails のデフォルトは html ですが、サーバー ログはレンダリングされます。

以上のことを踏まえて、その他の調査結果を次に示します。

Started GET "/users/companies/1/divisions/18/job_postings/349421/applications" for 127.0.0.1 at 2012-10-03 19:55:26 -0400
Processing by Users::JobPostingApplicationsController#index as JSON

(このペーストで上記のリクエスト全体を参照できます)

このリクエストでJSONを提供しておらず、:jsonこのルートのデフォルト形式のルーティングに仕様がないことを考えると、JSONが私を超えているため、なぜそれが処理されているのか。

request.formatさらに、このアクション内での値をデバッグすると、 が返されますapplication/json

提示された別のシナリオは、テンプレートusers/company_admin_metrics#indexのみを含む別のコントローラー ( ) 内にあります。index.html.slimこのページに移動すると、サーバー ログにusers/company_admin_metrics/index.html.slim内でレンダリングされたことが示されますlayouts/users。空の js.coffee テンプレートを作成すると:

$ touch app/views/users/company_admin_metrics/index.js.coffee

そのインデックス ページに直接移動すると、サーバー ログはそれがレンダリングされたことを示します。これによりusers/company_admin_metrics/index.js.coffee、テンプレートのレンダリングの優先順位に関する潜在的な問題がさらに明らかになります。

これに対する潜在的な修正を提供する可能性のある同様の問題に遭遇した人はいますか?

私たちのスタック

以下は、この特定の質問に対する基本的なプレーヤーのリストです。

  • レール 3.2.6
  • コーヒーレール 3.2.1
  • ベタータブ 1.2.6

このリクエストは、JSON を解析して Ruby オブジェクトを返すクライアント gem を介した求人情報 API へのリクエストに依存しますが、競合してこのアプリの content-type がapplication/json上記のような要求に対して。

4

3 に答える 3

12

.jsajax リクエストの URL にフォーマット拡張子を追加する必要があると思います。

おそらく起こっていることは、ユーザーがhtmlのリクエストでindexアクションを実行していることです。次に、ajax は同じ URL/アクションにヒットしますが、javascript を要求します。ユーザーが [戻る] ボタンをクリックすると、ブラウザーは 2 つの違いを認識できないため、最新のもの (JavaScript 応答) を使用します。/job_applicationsGET

于 2012-11-03T08:05:03.710 に答える
4

この質問が出されてから数か月が経ちましたが、この質問に出くわして以来、私は声を上げて2セントを差し上げます.

carbo が言ったように、ブラウザーは html と js リクエストの違いを見分けることができるので、戻るボタンをクリックすると、同じ URL が表示され、js コードに発生するキャッシュされたデータが表示されます。私はいくつかの問題を抱えていましたが、Ajax リクエストのブラウザ履歴を変更するためにプッシュ状態 JavaScript を使用していました。私が見つけた最も簡単な解決策は、リクエストをキャッシュしないようにブラウザに指示することでした。そのため、前のページに戻ると、強制的に再読み込みされます。

キャッシュをグローバルに無効にすることができます: $.ajaxSetup({ cache: false });

または、特定の ajax リクエストで cache false を指定してみてください。

于 2013-02-09T02:06:18.277 に答える