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

Home แก้ปัญหาหน้าเว็บ 404 หลังตั้ง Permalink ใน WordPress

แก้ปัญหาหน้าเว็บ 404 หลังตั้ง Permalink ใน WordPress

หลังจากเปลี่ยนโครงสร้างลิงก์ถาวร (Permalink) ใน WordPress จากแบบ ?p=123 เป็นแบบอ่านง่ายอย่าง /%postname%/ หลายเว็บเจออาการเดียวกัน คือหน้าแรกเปิดได้ปกติ แต่เมื่อคลิกเข้าบทความหรือหน้าใดก็ตามกลับขึ้น 404 Not Found บางครั้งเป็นหน้า 404 ของ WordPress เอง บางครั้งเป็นหน้า 404 เปล่าๆ ของ Web Server

สาเหตุเกือบทั้งหมดมาจากจุดเดียว: Web Server ไม่ได้ส่งคำขอ URL ที่ไม่ใช่ไฟล์จริงไปให้ index.php ของ WordPress จัดการ บทความนี้อธิบายวิธีไล่หาสาเหตุและแก้ไขทั้งบน Apache, Nginx, Plesk และ DirectAdmin

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

  • สิทธิ์ผู้ดูแล (Administrator) ในหลังบ้าน WordPress
  • สิทธิ์แก้ไขไฟล์ในโฟลเดอร์เว็บ ผ่าน File Manager ของ Plesk/DirectAdmin, SFTP หรือ SSH
  • หากเป็น Cloud Server ที่ดูแลเอง ต้องมีสิทธิ์ sudo เพื่อแก้ไฟล์ตั้งค่า Apache หรือ Nginx
  • สำรองไฟล์ .htaccess หรือไฟล์ตั้งค่า Web Server เดิมไว้ก่อนแก้ทุกครั้ง

ขั้นตอนที่ 1: รู้ก่อนว่าเว็บรันอยู่บน Web Server ตัวไหน

วิธีแก้ต่างกันตาม Web Server จึงควรตรวจให้แน่ใจก่อน รันคำสั่งนี้จากเครื่องใดก็ได้

curl -sI https://example.com/ | grep -i '^server'

ผลลัพธ์ที่มักเห็นคือ Server: Apache, Server: nginx หรือ Server: LiteSpeed สรุปแนวทางได้ดังนี้

Web Serverอ่านไฟล์ .htaccess หรือไม่จุดที่ต้องแก้
Apacheอ่าน (ถ้าเปิด AllowOverride).htaccess และ mod_rewrite
LiteSpeed / OpenLiteSpeedอ่าน (OpenLiteSpeed ต้องเปิด Auto Load from .htaccess).htaccess
Nginx ล้วนไม่อ่านไฟล์ Server Block (try_files)
Nginx หน้า Apache (แบบที่ Plesk และ DirectAdmin ใช้บ่อย)อ่านผ่าน Apache.htaccess
IIS (Windows Hosting)ไม่อ่านweb.config และ URL Rewrite Module

หมายเหตุ: ค่า Header Server อาจถูกซ่อนหรือแสดงเป็น nginx แม้ด้านหลังจะเป็น Apache ก็ได้ ถ้าไม่แน่ใจให้สอบถามผู้ดูแลระบบหรือดูที่แผงควบคุม

ขั้นตอนที่ 2: บันทึก Permalink ใหม่อีกครั้ง

วิธีที่ง่ายที่สุดและแก้ได้หลายกรณี คือให้ WordPress เขียนกฎ Rewrite ใหม่

  1. เข้าหลังบ้าน WordPress ไปที่ การตั้งค่า > ลิงก์ถาวร (Settings > Permalinks)
  2. ไม่ต้องเปลี่ยนอะไร กดปุ่ม บันทึกการเปลี่ยนแปลง (Save Changes)
  3. ลองเปิดบทความอีกครั้ง

ถ้าบนหน้าจอมีข้อความว่า WordPress เขียนไฟล์ .htaccess ไม่ได้ และแสดงโค้ดให้คัดลอกเอง แปลว่าสิทธิ์ไฟล์ไม่อนุญาต ให้ไปขั้นตอนที่ 3 ส่วนผู้ที่ใช้ WP-CLI ทำแบบเดียวกันได้ด้วยคำสั่ง

wp rewrite structure '/%postname%/'
wp rewrite flush --hard

ตัวเลือก --hard สั่งให้เขียนไฟล์ .htaccess ด้วย (มีผลเฉพาะบน Apache) ดูการใช้ WP-CLI เพิ่มเติมได้ที่ จัดการ WordPress ด้วย WP-CLI

ขั้นตอนที่ 3: ตรวจไฟล์ .htaccess (Apache และ LiteSpeed)

เปิดไฟล์ .htaccess ที่อยู่ในโฟลเดอร์เดียวกับ wp-config.php (เช่น httpdocs บน Plesk หรือ public_html บน DirectAdmin) ไฟล์นี้ขึ้นต้นด้วยจุด บาง File Manager จะซ่อนไว้ ต้องเปิดตัวเลือกแสดงไฟล์ซ่อนก่อน เนื้อหามาตรฐานของ WordPress คือ

# BEGIN WordPress
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]
RewriteBase /
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
</IfModule>
# END WordPress

ถ้าไฟล์ไม่มีบล็อกนี้ ให้เพิ่มเข้าไป ถ้าติดตั้ง WordPress ไว้ในโฟลเดอร์ย่อย เช่น https://example.com/blog/ ให้แก้สองบรรทัดเป็น RewriteBase /blog/ และ RewriteRule . /blog/index.php [L]

ตรวจสิทธิ์ไฟล์ให้ WordPress เขียนได้ในครั้งต่อไป โดยปกติ 644 ก็เพียงพอ หากเจ้าของไฟล์ตรงกับผู้ใช้ที่ PHP ทำงานอยู่

ls -l /var/www/example.com/.htaccess
chmod 644 /var/www/example.com/.htaccess

รายละเอียดเรื่องสิทธิ์ไฟล์อ่านต่อได้ที่ ทำความเข้าใจสิทธิ์ไฟล์บน Linux ด้วย chmod และ chown

ขั้นตอนที่ 4: เปิด mod_rewrite และ AllowOverride (Cloud Server ที่ใช้ Apache)

ถ้า .htaccess ถูกต้องแล้วแต่ยังเป็น 404 มักเป็นเพราะ Apache ไม่อ่านไฟล์นี้เลย ค่าเริ่มต้นของทั้ง Ubuntu และ AlmaLinux/Rocky ตั้ง AllowOverride None ไว้

Ubuntu 22.04 / 24.04

sudo a2enmod rewrite

จากนั้นแก้ไฟล์ Virtual Host ของเว็บ เช่น /etc/apache2/sites-available/example.com.conf ให้มีบล็อกนี้อยู่ภายใน <VirtualHost>

<Directory /var/www/example.com>
    AllowOverride All
    Require all granted
</Directory>
sudo apache2ctl configtest
sudo systemctl reload apache2

คำสั่ง configtest ต้องตอบว่า Syntax OK ก่อนจึง reload

AlmaLinux / Rocky Linux 8-9

mod_rewrite ถูกโหลดไว้แล้วโดยค่าเริ่มต้น ตรวจได้ด้วย

httpd -M | grep rewrite

ควรเห็น rewrite_module (shared) จากนั้นเพิ่มบล็อก <Directory> แบบเดียวกันในไฟล์ใต้ /etc/httpd/conf.d/ หรือแก้บล็อก <Directory "/var/www/html"> ใน /etc/httpd/conf/httpd.conf ให้เป็น AllowOverride All แล้ว

sudo apachectl configtest
sudo systemctl reload httpd

ขั้นตอนที่ 5: เพิ่ม try_files (Nginx ล้วน)

Nginx ไม่อ่าน .htaccess การบันทึก Permalink ในหลังบ้านจึงไม่มีผลใดๆ ต้องแก้ใน Server Block ของเว็บ (Ubuntu อยู่ที่ /etc/nginx/sites-available/, AlmaLinux/Rocky อยู่ที่ /etc/nginx/conf.d/)

location / {
    try_files $uri $uri/ /index.php?$args;
}

ถ้าติดตั้งในโฟลเดอร์ย่อย /blog/ ให้ใช้

location /blog/ {
    try_files $uri $uri/ /blog/index.php?$args;
}
sudo nginx -t
sudo systemctl reload nginx

nginx -t ต้องแสดง syntax is ok และ test is successful ถ้ายังไม่เคยตั้ง Server Block ดูตัวอย่างเต็มได้ที่ ติดตั้ง Nginx, PHP-FPM และ MariaDB (LEMP) บน Ubuntu

ขั้นตอนที่ 6: กรณีใช้แผงควบคุม

Plesk

บน Plesk แบบ Linux ค่าเริ่มต้นคือ Nginx ทำหน้าที่ Proxy ส่งต่อให้ Apache ซึ่งอ่าน .htaccess ได้ตามปกติ แต่ถ้ามีการปิด Proxy mode (ให้ Nginx เสิร์ฟ PHP เอง) .htaccess จะไม่มีผล ให้ไปที่ Websites & Domains เลือกโดเมน แล้วเปิด Apache & nginx Settings (บางเวอร์ชันอยู่ใต้แท็บ Hosting & DNS) ตรวจว่าเปิด Proxy mode ไว้ หรือถ้าตั้งใจใช้ Nginx อย่างเดียว ให้ใส่ใน Additional nginx directives

if (!-e $request_filename) {
    rewrite ^(.*)$ /index.php last;
}

ถ้าเป็น Plesk บน Windows (IIS) ให้ติดตั้งผ่าน WordPress Toolkit หรือใช้ไฟล์ web.config ที่มีกฎ URL Rewrite ส่งคำขอที่ไม่ใช่ไฟล์หรือโฟลเดอร์ไปยัง index.php

DirectAdmin

DirectAdmin ส่วนใหญ่ใช้ Apache หรือ LiteSpeed ซึ่งอ่าน .htaccess อยู่แล้ว ให้แก้ไฟล์ใน public_html ผ่าน File Manager ตามขั้นตอนที่ 3 ดูวิธีใช้ File Manager ได้ที่ จัดการไฟล์เว็บไซต์ด้วย File Manager บน DirectAdmin

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

ทดสอบด้วย curl กับ URL บทความจริง

curl -sI https://example.com/hello-world/ | head -n 1

ผลที่ถูกต้องคือ HTTP/2 200 หรือ HTTP/1.1 200 OK ถ้ายังเป็น 404 ให้ดูว่าเป็น 404 จาก WordPress (หน้าตาตามธีม) หรือจาก Web Server (หน้าขาวข้อความสั้น) ถ้าเป็นหน้าตามธีม แปลว่า Rewrite ทำงานแล้ว แต่ WordPress หาเนื้อหานั้นไม่เจอ ซึ่งเป็นปัญหาคนละเรื่องกัน

ควรทดสอบหน้าหมวดหมู่และหน้าที่มีเลขหน้า เช่น /category/news/page/2/ ด้วย เพราะใช้กฎชุดเดียวกัน

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

แก้แล้วเกิด 500 Internal Server Error

มักเกิดจากพิมพ์ .htaccess ผิด หรือใส่คำสั่งที่ Apache ไม่รู้จัก เช่นใส่ RewriteEngine ในเครื่องที่ไม่มี mod_rewrite โดยไม่มี <IfModule> ครอบ ให้คืนไฟล์สำรองแล้วดู Error Log (ดู ดู Log เว็บไซต์บน Plesk เพื่อหาสาเหตุ Error)

404 เฉพาะบางหน้า

ถ้าบทความส่วนใหญ่เปิดได้ แต่บางหน้า 404 ให้ตรวจว่า slug ซ้ำกับชื่อโฟลเดอร์จริงบนเซิร์ฟเวอร์หรือไม่ เช่นมีโฟลเดอร์ /shop/ อยู่จริง เงื่อนไข !-d จะทำให้ Web Server เสิร์ฟโฟลเดอร์นั้นแทน นอกจากนี้ปลั๊กอินแคชอาจเก็บผล 404 เก่าไว้ ให้ล้างแคชของปลั๊กอินและ CDN

ย้ายโฮสต์แล้ว 404 ทุกหน้า

ไฟล์ .htaccess มักหายไประหว่างย้าย เพราะเครื่องมือบางตัวไม่คัดลอกไฟล์ที่ขึ้นต้นด้วยจุด ให้สร้างใหม่ตามขั้นตอนที่ 3 และดูขั้นตอนย้ายที่ครบถ้วนได้ที่ ย้ายเว็บไซต์ WordPress ไปโฮสต์ใหม่

เปลี่ยนโครงสร้าง Permalink แล้วลิงก์เก่าจาก Google ตาย

ถ้าเว็บเคยใช้โครงสร้างแบบอื่นและถูกจัดทำดัชนีไว้แล้ว ควรทำ 301 Redirect จาก URL เดิมไปยัง URL ใหม่ ดู ทำ 301 Redirect ด้วยไฟล์ .htaccess หรือ ทำ 301 Redirect บน Nginx และอ่านความหมายของรหัสสถานะต่างๆ ได้ที่ ทำความเข้าใจ HTTP Error 403, 404, 500, 502, 503 และ 504

หากทำตามขั้นตอนแล้วยังแก้ไม่ได้ ติดต่อทีมงาน THAI DATA CLOUD ได้ที่ https://thaidata.cloud/contact/ โดยแจ้ง URL ที่เป็น 404 และชนิดบริการที่ใช้อยู่ เพื่อให้ตรวจสอบได้เร็วขึ้น

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

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