.htaccess เขียนซ้ำเพื่อเปลี่ยนเส้นทาง URL รากไปยังไดเรกทอรีย่อย


246

พยายามที่จะรับ

www.example.com

เพื่อไปที่

www.example.com/store

ฉันลองใช้รหัสหลายบิตแล้ว แต่ก็ไม่ทำงานเลย

สิ่งที่ฉันได้ลอง:

Options +FollowSymlinks
RewriteEngine on

RewriteCond %{HTTP_HOST} ^example.com$
RewriteRule (.*) http://www.example.com/$1 [R=301,L]

RewriteCond %{HTTP_HOST} ^(.+)\www.example\.com$
RewriteRule ^/(.*)$ /samle/%1/$1 [L]

ผมทำอะไรผิดหรือเปล่า?

คำตอบ:


275

คุณสามารถใช้กฎการเขียนซ้ำที่ใช้^ $เพื่อเป็นตัวแทนของรูทและเขียนซ้ำไปยังไดเร็กทอรี / store ของคุณเช่นนี้:

RewriteEngine On
RewriteRule ^$ /store [L]

6
RewriteRule ^ /? $ /index.do [R]
barclay

2
^ / $ ดูเหมือนจะไม่ตรงกันดังนั้นฉันเดาว่า ^ /? $ ไม่จำเป็น
NateS

เป็นไปได้ไหมที่จะแสดง URL แบบเต็มและดำเนินการตามกฎต่อไป ในกรณีของฉันฉันเขียน URL ใหม่เพื่อให้มันสวย สิ่งนี้จะเก็บ url example.com ไว้ - ฉันต้องการ example.com/store และดำเนินการต่อด้วยการเขียนซ้ำอื่น ๆ
gin93r

ทำงานได้ดีสำหรับฉันเช่นกัน
Jitesh Sojitra

1
เมื่อเร็ว ๆ นี้ฉันใช้เวลาในการดีบั๊กเพราะเหตุใดจึงไม่ทำงานบนไซต์ใน Ubuntu Apache 2.4.7 การดีบัก Rewrite แสดงให้เห็นว่ากฎถูกโจมตีและสร้างการไถ่ภายใน จากนั้นดูเหมือนว่าจะจอดเพียงนั้นและมองหาหน้าดัชนี ปรากฎว่าหาก mod_dir ถูกเปิดใช้งานและมีตัวเลือกหน้าดัชนีใน dir มันจะแทนที่ mod_rewrite เว้นแต่คุณตั้งค่า: DirectoryCheckHandler On
Gerrit

142

ฉันประหลาดใจที่ไม่มีใครพูดถึงเรื่องนี้:

RedirectMatch ^/$ /store/

โดยพื้นฐานแล้วมันจะเปลี่ยนเส้นทางรูทและ URL รูทเท่านั้น คำตอบมาจากลิงค์นี้


3
ขอบคุณมันใช้งานได้ดีสำหรับฉันด้วยกฎที่มีอยู่แล้ว ไม่มีความขัดแย้ง
วิทยาศาสตร์

1
อันนี้ทำงานได้อย่างสมบูรณ์ นอกจากนี้ยังครอบคลุมทั้ง http และ https
Sayem Shafayet

3
และนี่คือการเปลี่ยนเส้นทาง 301:RedirectMatch 301 ^/$ /store/
Andrea

ใช่มันง่ายกว่าด้วยการเขียนใหม่ ขอบคุณ!
Orden

2
@Andrea และสำหรับ 302 การเปลี่ยนเส้นทางชั่วคราว: RedirectMatch 302 ^ / $ / store /
Faizan Anwer Ali Rupani

108

ลองสิ่งนี้:

RewriteEngine on
RewriteCond %{HTTP_HOST} ^example\.com$
RewriteRule (.*) http://www.example.com/$1 [R=301,L]
RewriteRule ^$ store [L]

หากคุณต้องการเปลี่ยนเส้นทางภายนอก (ซึ่งทำให้เบราว์เซอร์ที่เข้าชมแสดง URL ที่เปลี่ยนเส้นทาง) ให้ตั้งค่าRสถานะที่นั่นเช่นกัน:

RewriteRule ^$ /store [L,R=301]

4
มันทำงานได้อย่างสวยงาม ทั้ง sample.com และ www.sample.com เปลี่ยนเส้นทางไปที่ www.sample.com/store นั่นคือสิ่งที่ฉันต้องการ ขอบคุณ Gumbo และทุกคนที่ตอบรับ ฉันเรียนรู้การอ่านคำตอบของคุณและชื่นชมความคิดเห็น

1
ฉันอยากรู้ว่ารายการนี้จะwww.example.comเป็น URI หลังจากเปลี่ยนเส้นทางหรือไม่ ถ้าไม่มันจะเปลี่ยนเป็นอย่างไร?
stefmikhail

1
♦ - และทำไมโซลูชั่นของคุณถึงดีกว่า Sander's down ด้านล่าง? ผมสังเกตเห็นบรรทัดสุดท้ายของคุณอยู่เหมือนกัน แต่ถ้านั่นคือสิ่งที่จำเป็นทำไมรวมRewriteCondและเป็นครั้งแรกRewriteRule?
stefmikhail

หากใช้รหัสนี้คุณสามารถพิมพ์เบราว์เซอร์ของคุณ exmple.com/../aboveSubDir ได้หรือไม่?

@GamErix จะมีการแก้ไข/aboveSubDirโดยเบราว์เซอร์หรือจากเซิร์ฟเวอร์
Gumbo

79

นี่คือสิ่งที่ฉันใช้เพื่อเปลี่ยนเส้นทางไปยังไดเรกทอรีย่อย มันทำอย่างล่องหนและยังอนุญาตผ่านคำขอที่ตรงกับไฟล์ที่มีอยู่หรืออะไรก็ตาม

RewriteEngine on
RewriteCond %{HTTP_HOST} ^(www.)?site.com$
RewriteCond %{REQUEST_URI} !^/subdir/
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ /subdir/$1
RewriteCond %{HTTP_HOST} ^(www.)?site.com$
RewriteRule ^(/)?$ subdir/index.php [L]

เปลี่ยน site.com และ subdir ด้วยค่าของคุณ


ทำงานได้ตามคาด! ที่ดี!
kachar

หน้าแรกคือ 'การซ่อนตัว' ... แต่เมื่อฉันคลิกลิงก์ชื่อ subdir จะปรากฏในแถบที่อยู่ ... มีวิธีป้องกันไม่ให้ชื่อ subdir แสดงขึ้นหรือไม่?
dsdsdsdsd

4
root เท่านั้น - ไม่ทำไดเรกทอรีย่อย
php-b-grader

3
สำหรับฉันมันให้ "Internal Server Error": /
Pithikos

1
ขอบคุณมากคุณไม่รู้ว่าฉันได้ค้นหามานานเท่าไรแล้ว
ความปรารถนาฐาน

26

หากต้องการตั้งค่าการเปลี่ยนเส้นทางที่มองไม่เห็นจากรูทเป็นโฟลเดอร์ย่อยคุณสามารถใช้ RewriteRule ต่อไปนี้ใน /root/.htaccess:

RewriteEngine on

RewriteCond %{REQUEST_URI} !^/subfolder
RewriteRule ^(.*)$ /subfolder/$1 [NC,L]

กฎข้างต้นจะเปลี่ยนเส้นทางเบราว์เซอร์จากภายใน:

ถึง

และ

ถึง

ในขณะที่เบราว์เซอร์จะยังคงอยู่ในโฟลเดอร์ราก


1
นี่ควรเป็นคำตอบที่ได้รับการยอมรับ ... RewriteRule พร้อม (ตามที่แนะนำในคำตอบอื่น ๆ ) ทำให้เกิดการเปลี่ยนเส้นทางไม่สิ้นสุดเนื่องจาก / โฟลเดอร์ย่อยถูกเปลี่ยนเส้นทางไปที่ / โฟลเดอร์ย่อย / โฟลเดอร์ย่อย ฯลฯ ... RewriteCond% {REQUEST_URI}! ^ / โฟลเดอร์ย่อย ตรวจสอบให้แน่ใจว่าหากมีการเปลี่ยนเส้นทาง URL แล้วจะไม่ดำเนินการอีกครั้ง
patrick

21

อีกทางเลือกหนึ่งหากคุณต้องการเขียน URL ใหม่และซ่อน URL เดิม:

RewriteEngine on
RewriteRule ^(.*)$ /store/$1 [L]

ด้วยวิธีนี้หากคุณพิมพ์ตัวอย่างhttp://www.example.com/product.php?id=4มันจะเปิดไฟล์ที่http://www.example.com/store/product.php?id=4แต่ไม่แสดง url แบบเต็มให้กับผู้ใช้


2
เพิ่มQSA(ต่อท้ายสตริงข้อความค้นหา) ไปที่[L]( [L, QSA]) หากคุณต้องการให้มีการสืบค้นสตริงข้อความไปยัง URL ที่เขียนใหม่
devios1

@chaiguy ขอบคุณสำหรับเคล็ดลับ แต่บนเซิร์ฟเวอร์ของฉันมันทำงานโดยไม่มี QSA (แต่ฉันยอมรับว่ามันอาจจะดีกว่าที่จะผนวก QSA) อาจเป็นเพราะการกำหนดค่าพิเศษของเซิร์ฟเวอร์ apache ของฉัน
gaborous

1
วิธีนี้สำหรับฉัน example.com แสดงเนื้อหาจาก example.com/store อย่างโปร่งใส แต่ example.com/test เปลี่ยนเส้นทางไปที่ example.com/store/test แสดง URL
Geoffrey Hale

14

นี่ดูเหมือนเป็นทางออกที่ง่ายที่สุด:

RewriteEngine on
RewriteCond %{REQUEST_URI} ^/$
RewriteRule (.*) http://www.example.com/store [R=301,L]

ฉันได้รับการเปลี่ยนเส้นทางลูปกับโซลูชั่นอื่น ๆ


2
อันนี้ไม่ซ่อนไดเรกทอรี
php-b-grader

8

ฉันไม่เข้าใจคำถามของคุณ ...

หากคุณต้องการเปลี่ยนเส้นทางทุกคำขอไปยังโฟลเดอร์ย่อย:

RewriteRule ^(.*)$ shop/$1 [L,QSA]

http://www.example.com/* -> wwwroot/store/*

หากคุณต้องการเปลี่ยนเส้นทางไปยังโฟลเดอร์ย่อยที่มีชื่อโดเมน

RewriteCond %{HTTP_HOST} ([^\.]+\.[^\.]+)$
RewriteRule ^(.*)$ %1/$1 [L,QSA]

http://www.example.com/* -> wwwroot/example.com/*

ฉันชอบรหัสของคุณ([^\.]+\.[^\.]+)$เพื่อจองโดเมนเป็นชื่อโฟลเดอร์ย่อย
Chetabahana

6

ฉันได้พบว่าเพื่อหลีกเลี่ยงการเปลี่ยนเส้นทางแบบวงกลมเป็นสิ่งสำคัญที่จะ จำกัด ขอบเขตของการเปลี่ยนเส้นทางไปยังไดเรกทอรีราก ฉันจะใช้:

RewriteEngine on
RewriteCond %{REQUEST_URI} ^/$
RewriteRule (.*) http://www.example.com/store [R=301,L]

6

โซลูชันด้านบนส่วนใหญ่นั้นถูกต้อง แต่ทั้งหมดนั้นขาดความโปร่งใสในการเปลี่ยนเส้นทาง

ในกรณีของฉันเมื่อเข้าสู่www.example.comฉันต้องการที่จะได้รับการเปลี่ยนเส้นทางไปยังไดเรกทอรีย่อย/ ร้านแต่ไม่มีการอัปเดต URL เพื่อwww.example.com/store (ทั้งหมดที่ฉันต้องการคือการได้รับแบบฟอร์มรหัสหน้าไดเรกทอรีที่) หากเป็นกรณีของคุณโซลูชันด้านล่างนี้ทำงานได้อย่างสมบูรณ์แบบ

RewriteEngine on
RewriteCond %{HTTP_HOST} example\.com [NC]
RewriteCond %{REQUEST_URI} ^/$
RewriteRule ^(.*)$ /store/$1 [L]

แหล่งที่มา: http://wiki.dreamhost.com/Transparently_redirect_your_root_directory_to_a_subdirectory


ฉันควรเปลี่ยนอะไรถ้าฉันต้องการให้ www.example.com เปลี่ยนเส้นทางไปที่ www.othersite.com/store โดยไม่ต้องอัปเดต URL ฉันพยายาม แต่ไม่สามารถปรับรหัสของคุณได้
ขั้นตอน

ฉันพยายามที่จะเปลี่ยนบรรทัดสุดท้ายเป็นRewriteRule ^(.*)$ http://otherpage.com/subfolder/$1 [L]แต่จะอัปเดต URL
ขั้นตอน

ทั้งหมดที่คุณต้องการก็คือการเปลี่ยนคำพูดและexample store
Mahmoud Zalt

ฉันไม่ได้อธิบายค่อนข้างดี ฉันเป็นเจ้าของexample.comและotherpage.comโดเมน เมื่อฉันเยี่ยมชมexample.comฉันต้องการให้เนื้อหาจากotherpage.com/subfolderที่จะแสดงโดยไม่ต้องอัปเดต URL
ขั้นตอน

ดีคำตอบของฉันข้างต้นไม่ทำอย่างนั้น ลองโพสต์คำถามใหม่
Mahmoud Zalt

5

หนึ่งสามารถใช้Redirectด้วยเพื่อจุดประสงค์นี้

Redirect 301 / www.example.com/store

หรือนามแฝงสำหรับการทำแผนที่

Alias / /store

แก้ไข: mod_alias ใช้งานได้ใน httpd.conf เท่านั้น

refrences


4

ก่อนหน้านี้ฉันใช้รหัสต่อไปนี้ซึ่งทำงานอย่างถูกต้องเพื่อเปลี่ยนเส้นทาง URL หลักของโดเมน / โดเมนย่อยแต่ละโดเมนไปยังไดเรกทอรีย่อยการติดต่อทางจดหมายซึ่งมีชื่อตรงกับโดเมนย่อยที่ตนเองตั้งไว้ด้านล่าง:

RewriteCond %{HTTP_HOST} ^sub1.domain1.com
RewriteCond %{REQUEST_URI} !subs/sub1.domain1.com/
RewriteRule ^(.*)$ subs/%{HTTP_HOST}/$1 [L,QSA]

RewriteCond %{HTTP_HOST} ^sub2.domain1.com
RewriteCond %{REQUEST_URI} !subs/sub1.domain2.com/
RewriteRule ^(.*)$ subs/%{HTTP_HOST}/$1 [L,QSA]

RewriteCond %{HTTP_HOST} ^sub1.domain2.com
RewriteCond %{REQUEST_URI} !subs/sub1.domain2.com/
RewriteRule ^(.*)$ subs/%{HTTP_HOST}/$1 [L,QSA]

RewriteCond %{HTTP_HOST} ^sub2.domain2.com
RewriteCond %{REQUEST_URI} !subs/sub2.domain2.com/
RewriteRule ^(.*)$ subs/%{HTTP_HOST}/$1 [L,QSA]

อย่างไรก็ตามเมื่อฉันต้องการเพิ่มหมวดย่อยหรือโดเมนอื่นก็จะต้องมีการเพิ่มในรหัสข้างต้น การเพิ่มความสะดวกในการทำงานเช่นไวด์การ์ด (*) นั้นง่ายกว่ามากดังนี้:

RewriteCond %{HTTP_HOST} ^sub
RewriteCond %{REQUEST_URI} !/subs/
RewriteRule ^(.*)$ subs/%{HTTP_HOST}/$1 [L,QSA]

ดังนั้นเมื่อใดก็ตามที่มีการเพิ่มโดเมนย่อย / โดเมนอื่นตราบใดที่ชื่อโดเมนย่อยมีส่วนนำหน้าย่อย (เช่น: sub3.domain1.com, sub1.domain3.com เป็นต้น) รหัสจะยังคงใช้งานได้


3

ฉันคิดว่าปัญหาหลักของรหัสที่คุณโพสต์คือ:

  • บรรทัดแรกตรงกับโฮสต์ที่เริ่มต้นด้วย sample.com อย่างเคร่งครัดดังนั้น www.sample.com จึงไม่ตรงกัน

  • บรรทัดที่สองต้องการอักขระอย่างน้อยหนึ่งตัวตามด้วย www.sample.com ซึ่งไม่ตรงกัน (ทำไมคุณถึงหลบเลี่ยงประโยคแรก)

  • ไม่มีกฎรวมอยู่ที่เปลี่ยนเส้นทางไปยัง URL ที่คุณระบุในเป้าหมายของคุณ (บวกตัวอย่างถูกสะกดผิดว่าเป็น samle แต่ไม่เกี่ยวข้องเลย)

สำหรับการอ้างอิงนี่คือรหัสที่คุณมีอยู่ในปัจจุบัน:

Options +FollowSymlinks
RewriteEngine on

RewriteCond %{HTTP_HOST} ^sample.com$
RewriteRule (.*) http://www.sample.com/$1 [R=301,L]

RewriteCond %{HTTP_HOST} ^(.+)\www.sample\.com$
RewriteRule ^/(.*)$ /samle/%1/$1 [L]

2

googling เล็กน้อยให้ผลลัพธ์เหล่านี้กับฉัน:

RewriteEngine ใน
RewriteBase /
RewriteRule ^ ดัชนี (. *)? $ http://domain.com/subfolder/ [r = 301]

นี่จะเปลี่ยนเส้นทางความพยายามในการเข้าถึงไฟล์ชื่อ index.something ไปยังโฟลเดอร์ย่อยของคุณไม่ว่าจะมีไฟล์อยู่หรือไม่ก็ตาม

หรือลองสิ่งนี้:

RewriteCond% {HTTP_HOST}! ^ www.sample.com $ [NC]
RewriteRule ^ (. *) $% {HTTP_HOST} / samlse / $ 1 [R = 301, L]

ฉันยังไม่ได้เปลี่ยนเส้นทางมากในไฟล์. htaccess ดังนั้นฉันจึงไม่แน่ใจว่าจะใช้งานได้หรือไม่


2

สองวิธีในการแก้ปัญหาที่เป็นไปได้ในการบรรลุเป้าหมายคือ: 1. สร้าง.htaccessไฟล์ในโฟลเดอร์รากตามใต้ (เพียงแทนที่ example.com และ my_dir ด้วยค่าที่สอดคล้องกันของคุณ):

<IfModule mod_rewrite.c>
RewriteEngine on
RewriteCond %{HTTP_HOST} ^(www.)?example.com$
RewriteCond %{REQUEST_URI} !^/my_dir/
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ /my_dir/$1
RewriteCond %{HTTP_HOST} ^(www.)?example.com$
RewriteRule ^(/)?$ my_dir/index.php [L] 
</IfModule>
  1. ใช้ RedirectMatch เพื่อเปลี่ยนเส้นทาง URL หลัก“ /” ไปยังโฟลเดอร์หรือ URL อื่นเท่านั้น

    RedirectMatch ^ / $ http://www.example.com/my_dir


1

ลองใช้บรรทัดด้านล่างใน htaccess

หมายเหตุ: คุณอาจต้องตรวจสอบชื่อ default.html ว่าอะไร

default.html เป็นไฟล์ที่โหลดตามค่าเริ่มต้นในโฟลเดอร์รูท

RewriteEngine

Redirect /default.html http://example.com/store/


0

คุณเพียงแค่เพิ่มรหัสนี้ลงในไฟล์. htaccess ของคุณ

<IfModule mod_rewrite.c>
    RewriteEngine On
    RewriteBase /
    RewriteRule ^index\.php$ - [L]
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteCond %{REQUEST_FILENAME} !-d
    RewriteRule . /folder/index.php [L]
</IfModule>

0

ฉันจะตอบคำถามเดิมโดยไม่ชี้ให้เห็นถึงไวยากรณ์ที่เป็นไปได้อีก (มีหลายคำตอบอื่น ๆ ) แต่โดยการชี้ให้เห็นสิ่งที่ฉันเคยต้องรับมือกับที่ใช้เวลาคิดว่า:

What am I doing wrong?

มีความเป็นไปได้ที่% {HTTP_HOST} ไม่ได้รับการเติมอย่างถูกต้องหรือไม่ทั้งหมด แม้ว่าฉันเพิ่งเห็นว่าเกิดขึ้นในเครื่องเดียวบนโฮสต์ที่ใช้ร่วมกันด้วย apache ที่กำหนดเองบางอย่าง 2.2 มันเป็นไปได้อย่างไรก็ตาม


0

นี่จะลองใช้ subdir ถ้าไฟล์นั้นไม่มีอยู่ในรูท ต้องการสิ่งนี้เมื่อฉันย้ายเว็บไซต์. html พื้นฐานที่คาดว่าจะทำงานที่ระดับรูทและผลักไปยังส่วนย่อย ใช้งานได้เฉพาะในกรณีที่ไฟล์ทั้งหมดแบน (ไม่มี. htaccess trickery ในส่วนย่อยที่เป็นไปได้) มีประโยชน์สำหรับสิ่งต่าง ๆ ที่ลิงก์เช่นไฟล์ css และ js

# Internal Redirect to subdir if file is found there.
RewriteEngine on
RewriteCond %{DOCUMENT_ROOT}/%{REQUEST_URI} !-s
RewriteCond %{DOCUMENT_ROOT}/subdir/%{REQUEST_URI} -s
RewriteRule ^(.*)$ /subdir/$1 [L]
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.