質問: 生半可な質問で、皆さんにお手数をおかけてしており、誠に申し訳ございません。 dameoさんが、いろいろ応対してくださり、私の拙い質問を整理してくださいました。 ありがたいことです。ここに、整理していただいた質問を掲載し直させていただきます。 何卒よろしくお願いします。 ・ー・ー<質問ここから>ー・ー・ー・ー・ ■実現したいこと サーバー上には (DocumentRoot)/dir/ (DocumentRoot)/dir.html はあるが、 (DocumentRoot)/dir/index.html はない(例外的にあるディレクトリもある) http://domain/dir http://domain/dir/ というリクエストを受けたとき、レスポンスで (DocumentRoot)/dir.html を返したい ※dir/とdir.htmlの組は数千単位で存在し、他にもディレクトリやファイルは存在する ※dir/index.*については後で考慮するので、当面無視する ※ただし/と/index.htmlへのリクエストについては、.htaccessで変更してはならない ■サブドメイン以下のディレクトリーとファイルがあります。 Subdomain/aaa/ Subdomain/bbb/ Subdomain/ccc/ Subdomain/wp/ Subdomain/aaa.html Subdomain/bbb.html Subdomain/ccc.html Subdomain/index.html Subdomain/index.php Subdomain/sitemap.xml Subdomain/bbb/ddd/ Subdomain/bbb/ddd.html Subdomain/ccc/eee/fff/ Subdomain/ccc/eee/fff.html ※ sitemap.xmlは、PRO-Sitemapsで出力されたファイルです。 ■実現手段 以下の.htaccessを用意し、(DocumentRoot)に設置した。 ーー<.htaccess全文>ーーーーー DefaultType text/html DirectoryIndex index.php index.html RewriteEngine On RewriteBase / RewriteEngine on RewriteCond %{REQUEST_FILENAME} !-d RewriteCond %{REQUEST_FILENAME}.html -f RewriteRule ^(.*)$ $1.html # BEGIN WordPress # `BEGIN WordPress` から `END WordPress` までのディレクティブ (行) は # 動的に生成され、WordPress フィルターによってのみ修正が可能です。 # これらのマーカー間にあるディレクティブへのいかなる変更も上書きされてしまいます。 RewriteEngine On RewriteBase / RewriteRule ^index\.php$ - [L] RewriteCond %{REQUEST_FILENAME} !-f RewriteCond %{REQUEST_FILENAME} !-d RewriteRule . /index.php [L] # END WordPress ーーーーー ■問題 以下のURLに対して、403が発生して困っている。 http://domain/dir -> 301でhttp://domain/dir/(↓)にリダイレクト http://domain/dir/ -> 403 ■1.試したこと (1).htaccessに以下を追記した。 RewriteCond %{REQUEST_FILENAME} -d RewriteRule ^(.*)$ $1.html ーー<.htaccess全文>ーーーーー DefaultType text/html DirectoryIndex index.php index.html RewriteEngine On RewriteBase / RewriteEngine on RewriteCond %{REQUEST_FILENAME} !-d RewriteCond %{REQUEST_FILENAME}.html -f RewriteRule ^(.*)$ $1.html RewriteCond %{REQUEST_FILENAME} -d RewriteRule ^(.*)$ $1.html # BEGIN WordPress # `BEGIN WordPress` から `END WordPress` までのディレクティブ (行) は # 動的に生成され、WordPress フィルターによってのみ修正が可能です。 # これらのマーカー間にあるディレクティブへのいかなる変更も上書きされてしまいます。 RewriteEngine On RewriteBase / RewriteRule ^index\.php$ - [L] RewriteCond %{REQUEST_FILENAME} !-f RewriteCond %{REQUEST_FILENAME} !-d RewriteRule . /index.php [L] # END WordPress ーーーーー →403が404になるだけだった。 ■質問 .htaccessを修正することで403を回避し、200でdir.htmlを返す方法を教えて欲しい ■2.試したこと (1).htaccessに以下を追記した。 RewriteCond %{REQUEST_URI} !\. RewriteCond %{REQUEST_FILENAME}.html -f RewriteRule .* %{REQUEST_URI}.html [L] RewriteCond %{REQUEST_URI} !\. RewriteCond %{REQUEST_FILENAME}../$1.html -f RewriteRule (.*)/$ $1.html [L] ーー<.htaccess全文>ーーーーー DefaultType text/html DirectoryIndex index.php index.html RewriteEngine On RewriteBase / RewriteCond %{REQUEST_URI} !\. RewriteCond %{REQUEST_FILENAME}.html -f RewriteRule .* %{REQUEST_URI}.html [L] RewriteCond %{REQUEST_URI} !\. RewriteCond %{REQUEST_FILENAME}../$1.html -f RewriteRule (.*)/$ $1.html [L] # BEGIN WordPress # `BEGIN WordPress` から `END WordPress` までのディレクティブ (行) は # 動的に生成され、WordPress フィルターによってのみ修正が可能です。 # これらのマーカー間にあるディレクティブへのいかなる変更も上書きされてしまいます。 RewriteEngine On RewriteBase / RewriteRule ^index\.php$ - [L] RewriteCond %{REQUEST_FILENAME} !-f RewriteCond %{REQUEST_FILENAME} !-d RewriteRule . /index.php [L] # END WordPress ーーーーー ・http://subdomain.domain.info/ → OK(併存しているWPのindex.phpが表示される) ・http://subdomain.domain.info.index.html → OK(静的HTMLが表示され、ページ内リンクOK) ・http://subdomain.domain.info/aaa/ → 表示が崩れ、ページの内同じディレクトリのリンクが404となる (手入力 http://subdomain.domain.info/bbb/ddd.html → OK) ・http://subdomain.domain.info/aaa/1234 → OK (手入力 http://subdomain.domain.info/bbb/1234.html → OK) ・http://subdomain.domain.info/bbb/ddd/ → 403 (手入力 http://subdomain.domain.info/bbb/ddd.html → OK) ・http://subdomain.domain.info/ccc/eee/fff/ → 403 (手入力 http://subdomain.domain.info/ccc/eee/fff.html → OK) ■質問 .htaccessを修正することで403を回避し、200でdir.htmlを返す方法を教えて欲しい ■3.試したこと (1).htaccessに以下を追記した。 RewriteCond %{REQUEST_FILENAME} -d RewriteRule (.*)/$ $1.html [L] ーー<.htaccess全文>ーーーーー DefaultType text/html DirectoryIndex index.php index.html RewriteEngine On RewriteBase / RewriteCond %{REQUEST_URI} !\. RewriteCond %{REQUEST_FILENAME}.html -f RewriteRule .* %{REQUEST_URI}.html [L] RewriteCond %{REQUEST_URI} !\. RewriteCond %{REQUEST_FILENAME}../$1.html -f RewriteRule (.*)/$ $1.html [L] RewriteCond %{REQUEST_FILENAME} -d RewriteRule (.*)/$ $1.html [L] # BEGIN WordPress # BEGIN WordPress から END WordPress までのディレクティブ (行) は # 動的に生成され、WordPress フィルターによってのみ修正が可能です。 # これらのマーカー間にあるディレクティブへのいかなる変更も上書きされてしまいます。 RewriteEngine On RewriteBase / RewriteRule ^index\.php$ - [L] RewriteCond %{REQUEST_FILENAME} !-f RewriteCond %{REQUEST_FILENAME} !-d RewriteRule . /index.php [L] # END WordPress ーーーーー → 結果、403、404は返されなくなった。しかし、表示が崩れ、ページの内同じディレクトリのリンクが404となる ・http://subdomain.domain.info/ → OK(併存しているWPのindex.phpが表示される) ・http://subdomain.domain.info.index.html → OK(静的HTMLが表示され、ページ内リンクOK) ・http://subdomain.domain.info/aaa/1234 → OK (手入力 http://subdomain.domain.info/bbb/1234.html → OK) ・http://subdomain.domain.info/bbb/ddd/ → 表示されるが、表示が崩れ、ページの内同じディレクトリのリンクが404 (手入力 http://subdomain.domain.info/bbb/ddd.html → OK) ・http://subdomain.domain.info/ccc/eee/fff/ → 表示されるが、表示が崩れ、ページの内同じディレクトリのリンクが404 (手入力 http://subdomain.domain.info/ccc/eee/fff.html → OK) ■質問 .htaccessを修正することで、表示が崩れず、xxx.htmlと同様の表示になる方法を教えて欲しい ■補足 レンタルサーバ: X SERVER WEBサーバー: nginx ・ー・<最初の質問・ここから>ー・ー・ー・ー・ー・ー・ー・ URLに.(ドット)を含まない場合はディレクトリと見なして末尾スラッシュ補完 .htaccess初心者です。希望は、 「.htaccessで、URLに.(ドット)を含まない場合はディレクトリと見なさないで末尾に.html補完をさせたい」です。 ちなみに、このような例文をネットで教えていただきました。 RewriteCond %{REQUEST_URI} !/$ RewriteCond %{REQUEST_URI} !\.[^/\.]+$ RewriteRule .* %{REQUEST_URI}/ [L,R] もしかして、「.htaccessで、URLに.(ドット)を含まない場合はディレクトリと見なさないで末尾に.htmlを補完させたい」を実現できるのではないかと思い、質問させていただきます。 何卒、よろしくお願いいたします。 ・ー・<最初の質問・ここまで>ー・ー・ー・ー・ー・ー・ー・
回答: 文字通りの「URLに.(ドット)を含まない場合」だと、URLのドメイン部分に必ずドットはあるので、該当URL無しです。 「URLのパス名部分にURLに.(ドット)を含まない場合は末尾に.htmlを補完」なら、必要十分な記述は、 ``` RewriteEngine On RewriteCond %{REQUEST_URI} !\. RewriteRule .* %{REQUEST_URI}.html [L] ``` です。リダイレクトしたい場合(HTMLファイルの内容を応答するだけじゃなくて、ブラウザのアドレスバーも書き換えたい場合)は、`[L]`を`[L,R=301]`にします。 これだと、 ``` https://example.com/ ⇒ https://example.com/.html https://example.com/foo/ ⇒ https://example.com/foo/.html https://example.com/foo.bar ⇒ https://example.com/foo.bar https://example.com/foo.bar/baz ⇒ https://example.com/foo.bar/baz ``` で、1つめと2つめは多分まずそうです。「そういう名前のファイルが存在するときは」を条件に加えると、 ``` RewriteEngine On RewriteCond %{REQUEST_URI} !\. #RewriteCond %{REQUEST_URI}.html -f ・・・・・この行間違い RewriteCond %{REQUEST_FILENAME}.html -f RewriteRule .* %{REQUEST_URI}.html [L] ``` 4つ目のような、ディレクトリ部分にのみドットがある場合にも`.html`を付ける場合は、 2行目の`!\.`を引用されているような`!\.[^/\.]+$`にします。 (2つ目の`\`は不要なので`!\.[^/.]+$`でいいです) 追記 == すいません。まず前回の付け足し部分に間違いがありましたので訂正しておきます。 `REQUEST_URI`→`REQUEST_FILENAME` 最初の質問と違いますね。 というか、最初の質問が書き足りてなかったのか。今後の質問では、最初からちゃんと全部書いてください。 http://example.com/dir に.htmlを付加するだけでなく http://example.com/dir/ に対して末尾の/を取って.htmlを付加するのであれば、 ``` RewriteEngine On RewriteBase / RewriteCond %{REQUEST_URI} !\. RewriteCond %{REQUEST_FILENAME}.html -f RewriteRule .* %{REQUEST_URI}.html [L] RewriteCond %{REQUEST_URI} !\. RewriteCond %{REQUEST_FILENAME}../$1.html -f RewriteRule (.*)/$ $1.html [L] ``` で、どうでしょうか。