1

私は、Ruby on Rails 3.0に移植している、数百の散在するHTMLファイルと非フレームワークPHPファイルを含むサイトを継承しました。

Railsアプリに機能が追加されると、対応するページがドキュメントルートから削除されます。ただし、Googleや外部サイトからこれらへのリンクが頻繁に存在するため、404を返すだけでは受け入れられません。

たとえば、「/ contact.php」のようなURLは、「/ app /contact/」にリダイレクトする必要があります。

この最初のいくつかのケースでは、リダイレクトを実行するためのメタタグを使用して、古い場所に単純なスタブhtmlファイルを作成しました。これは、特に何千もの製品ページを置き換え始めたら、うまく拡張できません。

私の好みは、古いページを削除してから、404ハンドラーにこれらを新しいRailsアプリにディスパッチさせることです。このアプリは、正規表現とデータベースルックアップを使用してURLを調べ、置換ページが何であるかを調べてから、それに301リダイレクトを発行します。新しいページ。

httpd.confに、ディレクティブを配置しました。

ErrorDocument 404 /app/error/handle404
# /app/error is a rails url.

「http:// localhost / does-not-exist」を押すと、期待どおりにErrorControllerが呼び出されます。

ただし、コントローラー内で、request、request.headers、またはENVのどこにも元のパス( "/ does-not-exist")が見つかりません-request.request_uri(/ app /を含む)のような可能性のあるメソッドを呼び出していますerror / handle404)、および予期された元のパスを見つけずにrequest.headersとENVを調べます。

Apache access_logは、/ does-not-existのリクエストのみを表示し、/ app / error / handle404を透過的に呼び出したことを示します(リダイレクトを実行したり、2番目のリクエストを作成したりすることはありません)。

元のURLにアクセスするにはどうすればよいですか?

編集:明確にするために、ここに一連のイベントがあります:

  1. ユーザーはhttp://mysite/foo.phpのようなレガシーパスにヒットします。これは、おそらくブログの古いリンクから来ています。
  2. ...しかし、foo.phpはもう存在しません!
  3. これは404であるため、ApacheはErrorDocumentを呼び出します
  4. ディレクティブは「ErrorDocument404/railsapp / error/handle404」です。
  5. RailsはこれをErrorControllerアクション「handle404」にルーティングします-これは正しく機能しています
  6. 問題: ErrorControllerでは、request.request.uri、request.headersは、「/ foo.php」のように、ユーザーが実際にアクセスしようとしたURLに関する手がかりを提供しません。適切な置換ページを提供するには、元のURLを知る必要があります。
4

1 に答える 1

0

Railsリクエストで元の書き換えられていないURLを見つけることができなかったので、PHPでそれを行うことになりました-明示的なmysqli_ *()呼び出しを備えた、プレーンで昔ながらの非フレームワークPHPです。

PHP エラー ハンドラは、必要な情報を $_SERVER ハッシュで受け取ります。$_SERVER['REQUEST_URI'] には、必要な元の URI が含まれています。

これをデータベースで調べ、対応するエントリが見つかった場合は、新しい場所への 301 リダイレクトを発行します。エントリがない場合は、単に 404 ページをユーザーに表示します。

簡略化 (PHP):

$url = $_SERVER['REQUEST_URI'];
$redir = lookupRedirect($url);   # database stuff here
if (! $redir) {
    include ('404.phtml');
} else {
    header("Status: 301");
    header("Location: " . $redir['new_url']);
}

見苦しいですが、Rails アプリにエラー URL を認識させる方法が見つかりませんでした。

于 2011-05-18T16:28:20.093 に答える