cari

Rumah  >  Soal Jawab  >  teks badan

Diterangkan: Memahami mod_rewrite, penulisan semula URL dan mencipta "pautan cantik"

"Pautan cantik" ialah topik yang sering diminta, tetapi jarang dijelaskan sepenuhnya. mod_rewrite ialah satu cara untuk membuat "pautan cantik", tetapi ia rumit, sintaksnya sangat ringkas, sukar difahami, dan dokumentasi menganggap beberapa kebiasaan dengan HTTP. Bolehkah seseorang menerangkan secara ringkas cara "pautan cantik" berfungsi dan cara menggunakan mod_rewrite untuk menciptanya?

Nama biasa lain, alias, istilah untuk URL bersih: URL RESTful, URL mesra pengguna, URL mesra SEO, slugging dan URL MVC (mungkin nama yang salah)

P粉501007768P粉501007768391 hari yang lalu754

membalas semua(2)saya akan balas

  • P粉276064178

    P粉2760641782023-10-21 11:08:48

    Untuk mengembangkan jawapan deceze, saya ingin memberikan beberapa contoh dan penjelasan tentang beberapa fungsi mod_rewrite yang lain.

    Semua contoh di bawah menganggap anda sudah menggunakan .htaccess 文件中包含 RewriteEngine On.

    Tulis semula contoh

    Mari kita ambil contoh:

    RewriteRule ^blog/([0-9]+)/([A-Za-z0-9-\+]+)/?$ /blog/index.php?id=&title= [NC,L,QSA]

    Peraturan ini terbahagi kepada 4 bahagian:

    1. RewriteRule - Mula menulis semula peraturan
    2. ^blog/([0-9]+)/([A-Za-z0-9-+]+)/?$ - Ini dipanggil corak, tetapi saya hanya akan memanggilnya bahagian kiri peraturan - perkara yang anda mahu tolak
    3. blog/index.php?id=&title= - dipanggil penggantian, atau sebelah kanan peraturan tulis semula - perkara yang anda mahu tulis semula
    4. [NC,L,QSA] ialah bendera untuk peraturan menulis semula, dipisahkan dengan koma, saya akan menerangkannya secara terperinci kemudian

    Penulisan semula di atas akan membolehkan anda memaut ke kandungan seperti /blog/1/foo/ dan ia sebenarnya akan dimuatkan /blog/index.php?id=1&title=foo.

    Sebelah kiri peraturan

    • ^ 表示页面名称的开头 - 因此它将重写 example.com/blog/... 但不会重写 example.com/foo/博客/...^ mewakili permulaan nama halaman - jadi ia akan menulis semula
    • example.com/blog/... tetapi bukan
    • example.com/foo/blog/...< /code >(…)
        Setiap set kurungan
      • (…) mewakili ungkapan biasa, yang boleh kita tangkap sebagai pembolehubah di sebelah kanan peraturan. Dalam contoh ini: ([0-9]+) - 匹配长度至少为 1 个字符且仅包含数字值(即 0-9)的字符串。这可以通过规则右侧的
      • Set kurungan pertama -
      • ([0-9]+) - sepadan dengan rentetan yang panjangnya sekurang-kurangnya 1 aksara dan hanya mengandungi nilai angka (iaitu 0-9). Ini boleh dirujuk melalui -+ (注意 + 用反斜杠转义,因为如果不转义它,这将作为 正则表达式重复字符)。这可以通过规则右侧的 $1 di sebelah kanan peraturan
      Set kurungan kedua sepadan dengan rentetan sekurang-kurangnya 1 aksara panjangnya, mengandungi hanya aksara abjad angka (A-Z, a-z, atau 0-9) atau
    • - atau
    • + (nota ? 表示前面的字符是可选的,因此在本例中 /blog/1/foo//blog/1/foo+< / code> dilarikan dengan garis miring ke belakang kerana jika anda tidak melepaskannya, ini akan dilaksanakan sebagai ungkapan biasa Mengulang aksara
    • ). Ini boleh dirujuk melalui
    • $2 di sebelah kanan peraturan$

    ? bermaksud aksara sebelumnya adalah pilihan, jadi dalam kes ini

    dan /blog/1/foo code> akan ditulis semula pada kedudukan yang sama < /a>

    $ bermakna ini adalah penghujung rentetan yang ingin kita padankan/blog/1/foo//BLOG/1/ foo/

    🎜logo🎜 🎜Pilihan ini ditambah dalam kurungan segi empat sama pada penghujung peraturan tulis semula untuk menentukan syarat tertentu. Sekali lagi, anda boleh membaca tentang pelbagai bendera 🎜 dalam dokumentasi 🎜, tetapi saya akan membincangkan beberapa bendera yang lebih biasa: 🎜
    NC
    Bendera 🎜tanpa huruf besar bermaksud peraturan tulis semula tidak sensitif huruf besar-besaran, jadi untuk peraturan contoh di atas, ini bermakna 🎜 dan 🎜/BLOG/1/ foo/ (atau sebarang variasi daripadanya) akan dipadankan. 🎜
    L

    Bendera terakhir menunjukkan bahawa ini adalah peraturan terakhir yang perlu diproses. Ini bermakna jika dan hanya jika peraturan ini sepadan, tiada peraturan lanjut akan dinilai dalam proses pemprosesan penulisan semula semasa. Jika peraturan tidak sepadan, semua peraturan lain akan dicuba seperti biasa. Jika anda tidak menetapkan bendera L, semua peraturan berikutnya akan digunakan pada URL ditulis semula .

    END

    Sejak Apache 2.4, anda juga boleh menggunakan bendera [END]. Peraturan yang sepadan dengan ini akan [END] 标志。与之匹配的规则将完全终止进一步的别名/重写处理。 (而 [L]sepenuhnya

    menamatkan pemprosesan alias/penulisan semula selanjutnya. (Dan bendera [L] biasanya mencetuskan pusingan kedua, seperti semasa menulis semula subdirektori atau menulis semula subdirektori.)

    QSA
    /blog/1/foo/?comments=15 这样的内容将加载 /blog/index.php?id=1&title=foo&comments=15Bendera penambahan rentetan pertanyaan membolehkan kami menghantar pembolehubah tambahan ke URL yang ditentukan, yang akan ditambahkan pada parameter get asal. Untuk contoh kami ini bermaksud sesuatu seperti < /p>

    R
    R=301Bendera ini bukan yang saya gunakan dalam contoh di atas, tetapi saya fikir ia patut disebut. Ini membolehkan anda menentukan ubah hala http dan secara pilihan menyertakan kod status (cth.

    ). Contohnya, jika anda ingin melakukan ubah hala 301 pada /myblog/ ke /blog/, anda cuma tulis peraturan seperti ini:

    RewriteRule ^/myblog/(*.)$ /blog/ [R=301,QSA,L]

    Tulis semula syarat

    Syarat Tulis SemulaJadikan penulisan semula lebih berkuasa, membolehkan anda menentukan penulisan semula untuk situasi yang lebih khusus. Anda boleh membaca lebih lanjut mengenainya dalam Dokumentasi

    , tetapi saya akan menyemak beberapa contoh biasa dan menerangkannya:

    # if the host doesn't start with www. then add it and redirect
    RewriteCond %{HTTP_HOST} !^www\.
    RewriteRule ^ http://www.%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
    www. (如果尚不存在)并执行 301 重定向。例如,加载 http://example.com/blog/ 会将您重定向到 http://www.example.com/blog/Ini adalah amalan yang sangat biasa dan akan menambah

    di hadapan nama domain anda

    # if it cant find the image, try find the image on another domain
    RewriteCond %{REQUEST_URI} \.(jpg|jpeg|gif|png)$ [NC]
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteCond %{REQUEST_FILENAME} !-d
    RewriteRule (.*)$ http://www.example.com/ [L]

    Situasi ini agak kurang biasa, tetapi ini adalah contoh yang baik mengapa peraturan tidak akan dilaksanakan jika nama fail ialah direktori atau fail yang wujud pada pelayan.
    • %{REQUEST_URI} .(jpg|jpeg|gif|png)$ [NC]
    • Hanya fail dengan sambungan fail jpg, jpeg, gif atau png akan ditulis semula (tidak sensitif huruf besar-besaran).
    • %{REQUEST_FILENAME} !-f
    • akan menyemak sama ada fail itu wujud pada pelayan semasa dan melakukan penulisan semula jika ia tidak wujud
    • %{REQUEST_FILENAME} !-d
    • akan menyemak sama ada fail itu wujud pada pelayan semasa dan melakukan penulisan semula jika ia tidak wujud
    • Penulisan semula akan cuba memuatkan fail yang sama pada domain lain
    🎜

    balas
    0
  • P粉022140576

    P粉0221405762023-10-21 00:43:03

    Untuk memahami apa itu mod_rewrite, anda perlu terlebih dahulu memahami cara pelayan web berfungsi. Pelayan web bertindak balas kepada permintaan HTTP. Tahap paling asas permintaan HTTP kelihatan seperti ini:

    GET /foo/bar.html HTTP/1.1

    Ini adalah permintaan mudah daripada penyemak imbas ke pelayan web untuk URL /foo/bar.html. Adalah penting untuk menegaskan bahawa ia tidak meminta fail, ​​itu hanya meminta beberapa URL sewenang-wenangnya. Permintaan mungkin juga kelihatan seperti ini:

    GET /foo/bar?baz=42 HTTP/1.1

    Ini berfungsi sama seperti permintaan URL dan jelas sekali agnostik fail.

    Pelayan web ialah aplikasi yang mendengar pada port, menerima permintaan HTTP daripada port tersebut dan mengembalikan respons. Pelayan web adalah bebas sepenuhnya untuk membalas sebarang permintaan dalam apa jua cara yang difikirkan sesuai/untuk bertindak balas dalam apa jua cara yang anda konfigurasikan untuk bertindak balas. Respons ini bukan fail, tetapi Respons HTTP, yang mungkin atau mungkin tiada kaitan dengan mana-mana fail fizikal pada cakera. Pelayan web tidak semestinya Apache, terdapat banyak pelayan web lain, ia hanyalah program yang berjalan secara berterusan dan dilampirkan pada port yang bertindak balas kepada permintaan HTTP. Anda boleh menulis sendiri. Tujuan perenggan ini adalah untuk membolehkan anda melepasi sebarang tanggapan bahawa URL adalah setara secara langsung dengan fail, yang sangat penting untuk difahami. :)

    Konfigurasi lalai kebanyakan pelayan web adalah untuk mencari fail pada pemacu keras anda yang sepadan dengan URL. Jika document root pelayan ditetapkan kepada /var/www,它可能会查找文件/var/www/foo/bar. html wujud, layankannya jika wujud. Jika fail berakhir dengan ".php" ia akan memanggil jurubahasa PHP dan mengembalikan hasilnya. Semua perkaitan ini boleh dikonfigurasikan sepenuhnya; fail tidak perlu diakhiri dengan ".php" untuk pelayan web menjalankannya melalui penterjemah PHP, dan URL tidak perlu sepadan dengan mana-mana fail tertentu pada cakera untuk sesuatu berlaku.

    mod_rewrite ialah kaedah menulis semulapemprosesan permintaan dalaman. Apabila pelayan web menerima permintaan untuk URL /foo/bar, anda boleh menulis semula URL itu kepada sesuatu yang lain dan pelayan web akan mencari fail pada cakera yang sepadan dengannya. Contoh mudah:

    RewriteEngine On
    RewriteRule   /foo/bar /foo/baz

    Peraturan ini bermaksud apabila permintaan sepadan dengan "/foo/bar", tulis semula kepada "/foo/baz". Permintaan kemudiannya akan diproses seperti /foo/baz<相反,已请求 /code>. Ini boleh digunakan untuk pelbagai kesan seperti:

    RewriteRule (.*) .html

    Peraturan ini sepadan dengan apa-apa sahaja (.*) 并捕获它 ((..)),然后重写它以附加“.html” ”。换句话说,如果 /foo/bar 是请求的 URL,则将按照 /foo/bar.html.*) dan menangkap nya (

    (..)), kemudian menulisnya semula untuk menambahkan ".html". Dengan kata lain, jika

    adalah yang diminta URL, ia akan diproses seolah-olah ia telah diminta Lihat

    http://regular-expressions.info🎜 untuk butiran tentang pemadanan ekspresi biasa, tangkapan dan penggantian. 🎜Peraturan lain yang sering dihadapi ialah: 🎜
    RewriteRule (.*) index.php?url=

    Ini sekali lagi memadankan apa sahaja dan menulisnya semula ke fail index.php dan permintaan asal dalam url 查询参数中附加最初请求的 URL。即,对于传入的任何和所有请求,都会执行文件index.php,并且该文件将有权访问 $_GET['url'] supaya ia boleh melakukan apa sahaja yang dikehendaki dengannya.

    Mula-mula, anda meletakkan peraturan tulis semula ini ke dalam fail konfigurasi pelayan web anda. Apache juga membenarkan* anda memasukkannya ke dalam fail yang dipanggil .htaccess dalam akar dokumen (iaitu bersebelahan dengan fail .php).

    * jika dibenarkan oleh fail konfigurasi Apache utama; ia adalah pilihan tetapi biasanya didayakan.

    mod_rewrite tidak melakukan apa-apa

    mod_rewrite tidak akan menjadikan semua URL "cantik". Ini adalah tanggapan salah yang biasa. Jika anda mempunyai pautan ini dalam laman web anda:

    mod_rewrite tidak boleh menjadikannya cantik. Untuk menjadikannya pautan yang cantik anda mesti:

    1. Tukar pautan kepada pautan yang cantik:

    2. Gunakan mana-mana kaedah di atas untuk menggunakan mod_rewrite pada pelayan untuk mengendalikan permintaan untuk URL /my/pretty/link.

    (Anda boleh menggunakan mod_substitute< /a> bersama-sama dengan mengubah halaman HTML keluar dan pautan yang terkandung di dalamnya. Walaupun ini biasanya lebih susah daripada sekadar mengemas kini sumber HTML.)

    mod_rewrite boleh melakukan banyak perkara, anda boleh membuat peraturan padanan yang sangat kompleks, termasuk merantai beberapa penulisan semula, permintaan proksi kepada perkhidmatan atau mesin yang berbeza sepenuhnya, mengembalikan kod status HTTP tertentu sebagai respons, permintaan mengubah hala, dsb. Ia sangat berkuasa dan boleh menjadi sangat berguna jika anda memahami mekanisme tindak balas permintaan HTTP asas. Ia tidak secara automatik menjadikan pautan anda cantik.

    Sila rujuk dokumentasi rasmiuntuk semua kemungkinan bendera dan pilihan.

    balas
    0
  • Batalbalas