500の内部サーバーエラーページの動作を完全に正しく構成するのに問題があります。
主なユースケースは2つあります。
ヘッダーは送信されません
ここでの修正は簡単です。URLを変更せずにhttp500エラーをスローするだけです。
部分的なページエラー
この場合、いくつかのhtmlおよびhttpヘッダーはすでにクライアントに送信されています。部分的に壊れたページが表示されないようにするために、エラーページのURL/error.htmlに完全にリダイレクトするjavascriptを出力します。これは、通常のページの一部とエラーページの一部が表示されないようにするためです。また、専用に移動して、エラーメッセージが表示されるセクションが現在非表示になっている場合でも、結果のhtmlが最適ではないことを明確にします。エラーページ。
残念ながら、専用のエラーページから「戻る」を押すと、元のエラーページがキャッシュされ、その間にエラーが修正された場合でも、JavaScriptリダイレクトが再度実行されます。
たとえば、index.phpでヘッダーが送信された後にエラーが発生した場合、ユーザーを/error.htmlにリダイレクトするjavascriptが出力されます。そこに着いたら、ホームページに戻るか(問題ないはずです)、または反撃することができます。反撃すると、キャッシュされたページが表示され、error.htmlにリダイレクトされる場合があります。index.php> error.html(ヒットバック)キャッシュされたindex.php> error.html
この状況を回避するための理想的な方法は何ですか?
以下のコードでは、URLに#errorハッシュを追加して、最初にのみリダイレクトしようとします。その後、壊れた部分ページにアクセスすると、60秒の更新試行サイクルが開始されます。残念ながら、#errorハッシュとリダイレクトを設定してからヒットバックすると、index.php#errorではなくindex.phpに移動するため、キャッシュされた無限ループが発生します。
500ページの部分的なエラーを適切に処理するにはどうすればよいですか?
これが私のphpカスタムエラーハンドラーのコードです。これにより、上記の動作が発生します。
function showErrorPage() {
if (headers_sent()) {
// This is complicated due to the infastructure tending to have already sent headers, ...
// ...requiring a tuned javascript redirection in many instances.
// Output the following as html.
?>
<meta http-equiv="Cache-control" content="no-cache, no-store">
<script type='text/javascript'>
var currentHash = location.hash;
// UNFORTUNATELY, HERE THE HASH NEVER SHOWS AS SET!
if(!currentHash){ // If hash wasn't already set...
location.hash = '#error';
location.href = 'error.html'; // Redirect once.
} else { // Otherwise, the hash was already set, they were redirected once but came back.
// So just display this page for a time but refresh on a slow schedule.
setTimeout(function(){
location.reload(true); // Non-caching refresh.
}, 60*1000); // Reload after 1 min delay
}
</script>
<?php
} else {
// No headers sent, so set the right headers
header("HTTP/1.1 500 Internal Server Error");
header("Cache-Control: no-cache, must-revalidate"); // HTTP/1.1
header("Expires: Sat, 26 Jul 1997 05:00:00 GMT"); // Date in the past
}
// Regardless, include the visible error output and throw exit with error.
include(WEB_ROOT.'error.html');
exit(1);
}