.HTACCESS Membuat Rantai Pengalihan 301 yang Tidak Perlu - Bagaimana Cara Menghapusnya?
Tumpukan Saya:
- LAMPU
- Apache / 2.4.41
Informasi latar belakang:
Saya baru saja meluncurkan situs web baru untuk klien. Selama proses desain ulang kami memutuskan untuk:
- Beralih ke HTTPS di seluruh situs
- Hapus ekstensi .php dari URL
- Beralih ke CMS
Contoh URL LAMA:
http://www.example.com/courses/acme-course.php
Contoh URL BARU:
https://www.example.com/courses/acme-course
Masalah Saya:
Pengalihan 301 tambahan yang tidak perlu terjadi saat pengguna menavigasi ke salah satu URL LAMA.
Saya tidak mengerti mengapa pengalihan 301 tambahan dibuat dan tidak mengarahkan pengguna langsung ke URL tujuan yang benar menggunakan satu pengalihan 301.
Pengamatan Menarik:
Pengalihan 301 tambahan yang tidak perlu tidak terjadi saat saya menggunakan URL LAMA dengan HTTPS, bukan HTTP.
Contoh:
https://www.example.com/courses/acme-course.php
_
Menggunakan URL di atas dengan benar akan melakukan Pengalihan 301 dengan benar ke URL tujuan yang benar dari: https://www.example.com/courses/acme-course
Inilah Contoh 301 Redirect Chain:
URL Permintaan Asli:
http://www.example.com/courses/acme-course.php
1ST 301 Redirect (Tidak Diperlukan):
DARI:
http://www.example.com/courses/acme-course.php
UNTUK:
https://www.example.com/index.php?url=courses/acme-course.php
2ND 301 Redirect (Benar URL Tujuan Akhir):
DARI:
https://www.example.com/index.php?url=courses/acme-course.php
UNTUK:
https://www.example.com/courses/acme-course
Kode .htaccess saya:
# (1) General Settings
<IfModule mod_rewrite.c>
Options +FollowSymLinks
RewriteEngine On
</IfModule>
# (2) Force WWW
<IfModule mod_rewrite.c>
RewriteCond %{HTTPS} !=off
RewriteCond %{HTTP_HOST} !^www\. [NC]
RewriteCond %{SERVER_ADDR} !=127.0.0.1
RewriteCond %{SERVER_ADDR} !=::1
RewriteRule ^ %{ENV:PROTO}://www.%{HTTP_HOST}%{REQUEST_URI} [R=301,L]
</IfModule>
# (3) Force HTTPS
<IfModule mod_rewrite.c>
RewriteCond %{HTTPS} !=on
RewriteRule ^(.*)$ https://%{HTTP_HOST}/$1 [R=301,L]
</IfModule>
# (4) URL Routing for CMS
<IfModule mod_rewrite.c>
RewriteCond %{HTTPS} =on
RewriteRule ^ - [env=proto:https]
RewriteCond %{HTTPS} !=on
RewriteRule ^ - [env=proto:http]
## Check if file/directory exists
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
## Route all other URLs to index.php/URL
RewriteRule ^(.*)$ index.php?url=$1 [PT,L,QSA]
</IfModule>
Jawaban
Anda memiliki dua masalah utama ....
- Urutan Anda berada dalam urutan yang salah dalam
.htaccess
file. HTTP ke HTTPS danwww
pengalihan kanonis harus dilakukan sebelum pengontrol depan yang merutekan URL ke CMS Anda. Karenanya, pengalihan eksternal yang salah menjadi/index.php?url=courses/acme-course.php
- memperlihatkan struktur URL CMS internal Anda.
Penghapusan
.php
sebenarnya tidak dilakukan atas.htaccess
perintah Anda ?! Saya berasumsi ini harus dilakukan oleh aplikasi / logika CMS Anda? Akibatnya, ini akan selalu menghasilkan pengalihan kedua (karena.htaccess
mengalihkan ke HTTPS di jalur URL yang sama). Anda perlu melakukan sesuatu seperti berikut di bagian atas.htaccess
file Anda untuk menghapus.php
ekstensi.RewriteRule (.+)\.php$ https://www.example.com/$1 [R=301,L]
UPDATE: Jika saya menyusun ulang aturan / ketentuan, apakah penempatan Options + FollowSymlinks saya tetap sama?
Ini tidak benar-benar peduli di mana para Options
direktif terjadi. Namun, logis (dari sudut pandang keterbacaan) untuk menempatkannya di dekat bagian atas. (Perintah Apache tidak harus dijalankan sesuai urutan kemunculannya di file konfigurasi, karena setiap modul bekerja secara independen.)
Dengan asumsi Anda mengkodekan .htaccess
file Anda secara manual, maka file itu dapat dirapikan ...
Tidak diperlukan
<IfModule mod_rewrite.c>
pembungkus (multipel) . Apakah mod_rewrite opsional? Apakah situs Anda di-porting ke beberapa server di mana mod_rewrite tidak diaktifkan?Tidak perlu banyak
RewriteEngine
arahan. Contoh terakhir benar - benar menang dan mengontrol seluruh file.Banyak
<IfModule>
blok danRewriteEngine
tipikal sistem yang secara otomatis diedit oleh kode dan / atau dirancang untuk berfungsi tanpa diedit di beberapa server.
Jadi, .htaccess
file Anda harus ditulis ulang seperti ini dalam urutan ini:
Options +FollowSymlinks
# Enable the rewrite engine...
RewriteEngine On
# ----------------------------------------------------------------------
# | Forcing `https://` |
# ----------------------------------------------------------------------
# Redirect to HTTPS on the "same host" (requirement for HSTS)
RewriteCond %{HTTPS} !=on
RewriteRule (.*) https://%{HTTP_HOST}/$1 [R=301,L] # ---------------------------------------------------------------------- # | Forcing `www` | # ---------------------------------------------------------------------- RewriteCond %{HTTP_HOST} !^www\. RewriteCond %{SERVER_ADDR} !=127.0.0.1 RewriteCond %{SERVER_ADDR} !=::1 RewriteRule ^ https://www.%{HTTP_HOST}%{REQUEST_URI} [R=301,L] # ---------------------------------------------------------------------- # | URL Routing for CMS | # ---------------------------------------------------------------------- # (3) RewriteCond %{HTTPS} =on RewriteRule ^ - [env=proto:https] RewriteCond %{HTTPS} !=on RewriteRule ^ - [env=proto:http] # (4) - Check if physical file exists RewriteCond %{REQUEST_FILENAME} !-f RewriteCond %{REQUEST_FILENAME} !-d # (5) - Rewrite all other URLs to index.php/URL RewriteRule (.*) index.php?url=$1 [L,QSA]
Catatan tambahan:
The
PROTO
variabel lingkungan mengandung protokol apa pun yang sedang diminta. Dengan urutan pengalihan, ini sekarang akan selalu menjadi HTTPS. Alasan untuk variabel ini adalah agar CMS dapat mengalihkan ke HTTP jika HTTP diakses, atau HTTPS jika HTTPS diakses. Jika Anda memaksakan HTTPS maka itu tidak benar-benar berlaku. (Meskipun env var ini masih dapat digunakan oleh aplikasi Anda.)Jarang sekali Anda menggunakan
NC
bendera pada kondisi yang dinegasikan. Karenanya mengapa saya menghapusnya dari kondisi tersebut!^www\.
. Anda ingin mengalihkan ketika host tidak dimulai denganwww.
- semua huruf kecil. DenganNC
bendera itu akan gagal untuk mengalihkanWwW.
- meskipun ini akan sangat jarang.Saya telah menghapus pemeriksaan yang tidak perlu untuk HTTPS di pengalihan kanonik www.
The
PT
bendera pada yang terakhirRewriteRule
tidak diperlukan dalam.htaccess
. Dalam.htaccess
hal ini adalah perilaku default (melewati).Anda perlu membersihkan cache browser Anda sebelum menguji, karena pengalihan 301 yang salah kemungkinan besar telah di-cache oleh browser. Sebaiknya uji dengan 302 pengalihan (sementara) karena alasan ini.