私たちのチームは最近、ある種の 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
上記のような要求に対して。