ลดความยุ่งยากในการใช้คลาวด์ พูดคุยกับเจ้าหน้าที่

Home ทำ 301 Redirect ด้วยไฟล์ .htaccess

ทำ 301 Redirect ด้วยไฟล์ .htaccess

301 Redirect คือการบอกเบราว์เซอร์และ Search Engine ว่า URL นี้ย้ายไปอยู่ที่ใหม่อย่างถาวร Google จะค่อยๆ โอนสัญญาณการจัดอันดับจาก URL เดิมไปยัง URL ใหม่ ส่วนผู้เข้าชมที่คลิกลิงก์เก่าจะถูกพาไปหน้าใหม่โดยอัตโนมัติ จึงเป็นเครื่องมือหลักเมื่อเปลี่ยนโครงสร้าง URL, ย้ายหน้า, รวมหน้า หรือย้ายโดเมน

บนเว็บที่ใช้ Apache หรือ LiteSpeed (รวมถึงโฮสติ้ง Plesk และ DirectAdmin ส่วนใหญ่) วิธีที่สะดวกที่สุดคือเขียนกฎในไฟล์ .htaccess ที่อยู่ในโฟลเดอร์รากของเว็บ ไม่ต้องแก้ไฟล์ตั้งค่าของระบบและมีผลทันทีโดยไม่ต้องรีสตาร์ต

สิ่งที่ต้องเตรียม

  • สิทธิ์แก้ไขไฟล์ในโฟลเดอร์เว็บ (httpdocs บน Plesk, public_html บน DirectAdmin) ผ่าน File Manager, SFTP หรือ SSH
  • เว็บต้องรันบน Apache หรือ LiteSpeed ถ้าเป็น Nginx ล้วน ไฟล์ .htaccess จะไม่มีผล ให้ดู ทำ 301 Redirect บน Nginx แทน
  • รายการ URL เดิมและ URL ใหม่ที่ต้องการจับคู่ ควรทำเป็นตารางก่อนเริ่ม
  • สำเนาของไฟล์ .htaccess เดิม เพราะไฟล์ที่พิมพ์ผิดเพียงบรรทัดเดียวทำให้ทั้งเว็บขึ้น 500 Error ได้

ทำความรู้จักสองวิธีในการเขียน Redirect

วิธีโมดูลเหมาะกับ
Redirect / RedirectMatchmod_aliasย้ายหน้าทีละหน้า เขียนง่าย อ่านง่าย
RewriteCond + RewriteRulemod_rewriteเงื่อนไขตามโดเมน, HTTPS, Query String หรือรูปแบบซับซ้อน

ถ้าเว็บใช้ RewriteRule อยู่แล้ว เช่น WordPress, Laravel หรือ CMS ส่วนใหญ่ แนะนำให้เขียน Redirect ด้วย mod_rewrite ทั้งหมด เพราะเมื่อใช้สองโมดูลปนกัน ลำดับการทำงานไม่ได้เป็นไปตามลำดับบรรทัดในไฟล์ และอาจได้ผลที่ไม่คาดคิด

ขั้นตอนที่ 1: เปิดไฟล์ .htaccess และเลือกตำแหน่งที่วาง

ไฟล์ .htaccess เป็นไฟล์ซ่อน ต้องเปิดตัวเลือกแสดงไฟล์ซ่อนใน File Manager ก่อน กฎ Redirect ทั้งหมดต้องวาง ไว้เหนือ บล็อก # BEGIN WordPress หรือกฎ Rewrite ของ CMS เพราะกฎของ CMS จะส่งทุกคำขอไปที่ index.php และจบการประมวลผลด้วย [L] ถ้าวางไว้ด้านล่าง Redirect จะไม่มีโอกาสทำงาน

บรรทัดแรกของส่วนที่เพิ่มต้องมี

RewriteEngine On

ขั้นตอนที่ 2: เลือกกฎตามกรณีใช้งาน

ย้ายหน้าเดียว

RewriteRule ^old-page/?$ https://example.com/new-page/ [R=301,L]

ใน .htaccess เส้นทางที่นำมาเทียบจะไม่มีเครื่องหมาย / นำหน้า จึงเขียน ^old-page ไม่ใช่ ^/old-page ส่วน /? ทำให้รองรับทั้งแบบมีและไม่มี / ปิดท้าย

ถ้าเขียนด้วย mod_alias จะได้แบบนี้ (ต้องมี / นำหน้า)

Redirect 301 /old-page/ https://example.com/new-page/

ข้อควรระวัง: Redirect จับคู่แบบคำนำหน้า (prefix) คำขอ /old-page/abc จะถูกส่งไปที่ /new-page/abc ด้วย

ย้ายทั้งโฟลเดอร์ โดยเก็บส่วนท้ายของ URL ไว้

RewriteRule ^blog/(.*)$ https://example.com/news/$1 [R=301,L]

(.*) เก็บทุกอย่างหลัง blog/ ไว้ แล้วนำไปใส่แทน $1 เช่น /blog/2024/hello/ จะไปที่ /news/2024/hello/

บังคับใช้ HTTPS

RewriteCond %{HTTPS} off
RewriteRule ^ https://%{HTTP_HOST}%{REQUEST_URI} [R=301,L]

บน Plesk มีตัวเลือกในหน้าจอให้ทำได้โดยไม่ต้องเขียนเอง ดู บังคับเว็บไซต์ให้ใช้ HTTPS บน Plesk

รวมโดเมนให้เหลือแบบเดียว (www เป็นไม่มี www)

RewriteCond %{HTTP_HOST} ^www\.example\.com$ [NC]
RewriteRule ^ https://example.com%{REQUEST_URI} [R=301,L]

ถ้าต้องการให้ไปที่ www ให้กลับเงื่อนไขเป็น ^example\.com$ และเปลี่ยนปลายทางเป็น https://www.example.com เลือกเพียงแบบเดียวและใช้ให้ตรงกับ Canonical URL ของเว็บ

ย้ายทั้งโดเมน

วางไว้ใน .htaccess ของโดเมนเดิม (โดเมนเดิมต้องยังชี้มาที่เซิร์ฟเวอร์นี้)

RewriteCond %{HTTP_HOST} ^(www\.)?old-example\.com$ [NC]
RewriteRule ^ https://example.com%{REQUEST_URI} [R=301,L]

ควรคงโดเมนเดิมและ Redirect นี้ไว้อย่างน้อยหนึ่งปี และแจ้งการย้ายใน Google Search Console ด้วยเครื่องมือ Change of Address

URL เดิมที่มี Query String

RewriteRule มองไม่เห็นส่วนหลังเครื่องหมาย ? ต้องใช้ RewriteCond ตรวจ %{QUERY_STRING}

RewriteCond %{QUERY_STRING} (^|&)id=42(&|$)
RewriteRule ^product\.php$ https://example.com/products/widget/ [R=301,L,QSD]

แฟล็ก QSD (Apache 2.4 ขึ้นไป) ตัด Query String เดิมทิ้ง ถ้าไม่ใส่ ปลายทางจะกลายเป็น /products/widget/?id=42

ขั้นตอนที่ 3: ทดสอบด้วย 302 ก่อน แล้วค่อยเปลี่ยนเป็น 301

เบราว์เซอร์จำ 301 ไว้ในแคชนานมาก ถ้าเขียนผิดแล้วแก้ เบราว์เซอร์ที่เคยเปิดไปแล้วอาจยังไปที่ปลายทางผิดอยู่ ระหว่างทดสอบให้ใช้ R=302 เมื่อยืนยันว่าถูกต้องแล้วจึงเปลี่ยนเป็น R=301

ตัวอย่างไฟล์ที่สมบูรณ์

ตัวอย่างสำหรับเว็บ WordPress ที่บังคับ HTTPS, ตัด www และย้ายสองหน้า

RewriteEngine On

# 1) HTTPS และโดเมนหลักในขั้นตอนเดียว
RewriteCond %{HTTPS} off [OR]
RewriteCond %{HTTP_HOST} ^www\. [NC]
RewriteRule ^ https://example.com%{REQUEST_URI} [R=301,L]

# 2) หน้าที่ย้าย
RewriteRule ^about-us/?$ https://example.com/about/ [R=301,L]
RewriteRule ^blog/(.*)$ https://example.com/news/$1 [R=301,L]

# BEGIN WordPress
# (บล็อกเดิมของ WordPress ห้ามแก้ส่วนนี้)
# END WordPress

การรวม HTTPS และ www ไว้ในกฎเดียวทำให้ผู้เข้าชมถูก Redirect เพียงครั้งเดียว แทนที่จะวิ่งผ่านสองทอด (Redirect Chain) ซึ่งช้ากว่าและไม่ดีต่อ SEO

ตรวจสอบผลลัพธ์

ใช้ curl ดูเฉพาะ Header

curl -sI http://www.example.com/about-us/

ผลที่ถูกต้องควรมีสองบรรทัดสำคัญ

HTTP/1.1 301 Moved Permanently
Location: https://example.com/about/

ใช้ -L เพื่อตามทุกทอดและดูว่าจบที่ 200 หรือไม่

curl -sIL http://www.example.com/about-us/ | grep -iE '^(HTTP|location)'

ถ้าเห็น 301 มากกว่าหนึ่งครั้ง ให้ปรับกฎให้ไปปลายทางสุดท้ายในทอดเดียว ในเบราว์เซอร์ตรวจได้จาก DevTools แท็บ Network โดยติ๊ก Preserve log และ Disable cache

ปัญหาที่พบบ่อย

ERR_TOO_MANY_REDIRECTS

เกิดจาก Redirect วนกลับมาที่เดิม สาเหตุยอดนิยมคือใช้ Cloudflare โหมด Flexible หรือ Load Balancer ที่ส่งคำขอมาหาเซิร์ฟเวอร์เป็น HTTP ทำให้ %{HTTPS} เป็น off ตลอด แก้โดยตั้ง Cloudflare เป็น Full (strict) ดู เลือก SSL/TLS Mode บน Cloudflare ให้ถูกต้อง อีกสาเหตุคือปลั๊กอิน SEO หรือแผงควบคุมทำ Redirect ซ้ำกับกฎที่เขียนเอง ให้เลือกทำที่เดียว

ทั้งเว็บขึ้น 500 Internal Server Error

ไวยากรณ์ใน .htaccess ผิด ให้คืนไฟล์สำรองทันที แล้วดูข้อความใน Error Log ซึ่งมักบอกบรรทัดที่ผิด เช่น Invalid command หรือ RewriteRule: bad flag delimiters ดูวิธีเปิด Log ได้ที่ ดู Log เว็บไซต์บน Plesk เพื่อหาสาเหตุ Error

กฎไม่ทำงานเลย

ตรวจว่าวางไว้เหนือกฎของ CMS, ไม่ได้มี / นำหน้าใน Pattern ของ RewriteRule และ Apache อนุญาตให้อ่าน .htaccess (AllowOverride All) สำหรับ Cloud Server ที่ดูแลเอง ดูวิธีเปิดได้ใน แก้ปัญหาหน้าเว็บ 404 หลังตั้ง Permalink ใน WordPress

จุดในชื่อไฟล์ทำให้จับคู่ผิด

ใน Regular Expression จุด . หมายถึงอักขระใดก็ได้ ถ้าต้องการจุดจริงให้เขียน \. เช่น ^old\.html$

อ่านความหมายของรหัส 301, 302 และรหัสอื่นเพิ่มเติมได้ที่ ทำความเข้าใจ HTTP Error 403, 404, 500, 502, 503 และ 504 และหากต้องการความช่วยเหลือ ติดต่อทีมงาน THAI DATA CLOUD ได้ที่ https://thaidata.cloud/contact/

ผู้ให้บริการคลาวด์ไทย
เพื่อธุรกิจของคนไทย

"มุ่งมั่น" และ "มั่นคง"
พร้อมรับมือทุกการเติบโต
Trust Cloud
คลาว์ที่ปลอดภัย
คือรากฐานที่มั่นคง
cloud security