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

ทำ Redirect ระหว่าง www กับไม่มี www ให้ถูกวิธี
Home ทำ Redirect ระหว่าง www กับไม่มี www ให้ถูกวิธี

ทำ Redirect ระหว่าง www กับไม่มี www ให้ถูกวิธี

เว็บเดียวกันที่เข้าได้ทั้ง example.com และ www.example.com ถือเป็นสองเว็บในสายตาของเครื่องมือค้นหา ทำให้คะแนนความน่าเชื่อถือถูกแบ่งครึ่ง และเมื่อรวมกับ HTTP และ HTTPS จะกลายเป็นสี่เวอร์ชัน

คู่มือนี้บังคับให้ทุกทางเข้าไปจบที่ URL เดียว ด้วยการเปลี่ยนเส้นทางเพียงครั้งเดียว ซึ่งเป็นจุดที่หลายเว็บทำได้ไม่ดีเพราะเปลี่ยนเส้นทางหลายทอด

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

  • สิทธิ์แก้ไขคอนฟิกเว็บเซิร์ฟเวอร์หรือแผงควบคุม
  • ใบรับรอง SSL ที่ครอบคลุมทั้งสองรูปแบบ

ขั้นตอนที่ 1: เลือกรูปแบบหลัก

ทั้งสองแบบใช้ได้เท่ากันในแง่ SEO สิ่งสำคัญคือเลือกแล้วใช้อย่างสม่ำเสมอ

  • ไม่มี www สั้นกว่า จำง่ายกว่า เป็นที่นิยมในเว็บสมัยใหม่
  • มี www มีข้อได้เปรียบทางเทคนิคคือตั้ง CNAME ได้ ซึ่งจำเป็นเมื่อใช้ CDN บางเจ้า และแยกคุกกี้ออกจากโดเมนหลักได้

หากเว็บเปิดมานานแล้ว ให้เลือกแบบที่ Google เก็บดัชนีไว้มากกว่าเพื่อลดผลกระทบ

# ดูว่าแบบไหนถูกเก็บดัชนีมากกว่า ค้นหาใน Google
site:example.com
site:www.example.com

ขั้นตอนที่ 2: ตั้ง DNS ให้ทั้งสองชี้มาที่เดียวกัน

example.com.      IN  A      203.0.113.10
www.example.com.  IN  CNAME  example.com.

หรือใช้ A Record ทั้งคู่ก็ได้ ทั้งสองแบบทำงานเหมือนกัน

dig +short example.com
dig +short www.example.com

ขั้นตอนที่ 3: ขอใบรับรองให้ครอบคลุมทั้งสอง

sudo certbot --nginx -d example.com -d www.example.com --agree-tos -m [email protected]

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

echo | openssl s_client -connect example.com:443 -servername www.example.com 2>/dev/null \
  | openssl x509 -noout -text | grep -A1 'Subject Alternative Name'

ขั้นตอนที่ 4: ตั้ง Redirect บน Nginx

วิธีที่ถูกต้องคือแยก server block สำหรับชื่อที่ต้องการเปลี่ยนเส้นทาง ไม่ใช่ใช้ if ภายใน block เดียว

# HTTP ทั้งสองชื่อ ไปที่ HTTPS ของชื่อหลักโดยตรง ครั้งเดียวจบ
server {
    listen 80;
    server_name example.com www.example.com;
    return 301 https://example.com$request_uri;
}

# HTTPS ของ www ไปที่ HTTPS ของชื่อหลัก
server {
    listen 443 ssl;
    http2 on;
    server_name www.example.com;

    ssl_certificate     /etc/letsencrypt/live/example.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;

    return 301 https://example.com$request_uri;
}

# เว็บจริง
server {
    listen 443 ssl;
    http2 on;
    server_name example.com;

    ssl_certificate     /etc/letsencrypt/live/example.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;

    root /var/www/example.com;
    # ...
}
sudo nginx -t && sudo systemctl reload nginx

จุดสำคัญคือ block แรกส่ง HTTP ไปยัง HTTPS ของชื่อหลักโดยตรง ไม่ใช่ไป HTTPS ของ www ก่อนแล้วค่อยไปชื่อหลัก ซึ่งจะกลายเป็นสองทอด

ขั้นตอนที่ 5: ตั้งบน Apache

<VirtualHost *:80>
    ServerName example.com
    ServerAlias www.example.com
    Redirect permanent / https://example.com/
</VirtualHost>

<VirtualHost *:443>
    ServerName www.example.com
    SSLEngine on
    SSLCertificateFile    /etc/letsencrypt/live/example.com/fullchain.pem
    SSLCertificateKeyFile /etc/letsencrypt/live/example.com/privkey.pem
    Redirect permanent / https://example.com/
</VirtualHost>

หรือในไฟล์ .htaccess เมื่อไม่มีสิทธิ์แก้คอนฟิกหลัก

RewriteEngine On
RewriteCond %{HTTP_HOST} ^www\.(.+)$ [NC]
RewriteRule ^ https://%1%{REQUEST_URI} [L,R=301]

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

ขั้นตอนที่ 6: ตั้งบน Cloudflare

ใช้ Redirect Rules ซึ่งทำงานที่ขอบเครือข่ายจึงเร็วกว่าและไม่ต้องให้คำขอถึงเซิร์ฟเวอร์

ไปที่ Rules แล้ว Redirect Rules แล้วสร้างกฎใหม่

เงื่อนไข:  Hostname equals www.example.com
การกระทำ:  Dynamic redirect
Expression: concat("https://example.com", http.request.uri.path)
Status:    301
Preserve query string: เปิด

อย่าลืมเปิด Always Use HTTPS ในหน้า SSL/TLS แล้ว Edge Certificates ด้วย

ขั้นตอนที่ 7: ตั้งใน WordPress

ตั้งค่าที่ Settings แล้ว General ให้ทั้งสองช่องเป็นรูปแบบเดียวกัน

wp option get siteurl
wp option get home

wp option update siteurl 'https://example.com'
wp option update home 'https://example.com'

หากเคยใช้อีกรูปแบบมาก่อน ต้องแทนที่ URL ในเนื้อหาด้วย

wp search-replace 'https://www.example.com' 'https://example.com' \
  --all-tables --precise --recurse-objects --dry-run

ขั้นตอนที่ 8: ตรวจสอบว่าเปลี่ยนเส้นทางครั้งเดียว

for u in http://example.com/ http://www.example.com/ \
         https://www.example.com/ http://example.com/about/; do
  echo "=== $u"
  curl -sIL "$u" | grep -E '^HTTP|^[Ll]ocation'
done

ผลที่ถูกต้องคือแต่ละ URL แสดง 301 เพียงหนึ่งครั้งแล้วตามด้วย 200 หากเห็น 301 สองครั้งขึ้นไป แปลว่าเปลี่ยนเส้นทางหลายทอดซึ่งทำให้ช้าลงและเสียคะแนน SEO

ตรวจว่าพาธและพารามิเตอร์ถูกรักษาไว้

curl -sI 'https://www.example.com/blog/article/?utm_source=fb' | grep -i location

ควรได้ https://example.com/blog/article/?utm_source=fb ไม่ใช่แค่หน้าแรก

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

เปลี่ยนเส้นทางวนไม่รู้จบ

มักเกิดจาก Cloudflare ที่ตั้ง SSL เป็น Flexible ร่วมกับเซิร์ฟเวอร์ที่บังคับ HTTPS อยู่แล้ว เปลี่ยนเป็น Full (strict) หรือเกิดจากกฎที่ชี้กลับมาหาตัวเอง ตรวจด้วย curl -sIL แล้วดูว่าวนที่ URL ไหน

เปลี่ยนเส้นทางไปหน้าแรกเสมอ

คอนฟิกไม่ได้ส่งพาธต่อไปด้วย ใช้ $request_uri ใน Nginx หรือ %{REQUEST_URI} ใน Apache ไม่ใช่เขียน URL ปลายทางแบบตายตัว

เบราว์เซอร์จำการเปลี่ยนเส้นทางเก่าไว้

301 ถูกแคชในเบราว์เซอร์อย่างถาวร ระหว่างทดสอบให้ใช้ curl หรือโหมดไม่ระบุตัวตน และหากตั้งผิดไปแล้ว ผู้ใช้บางส่วนจะยังถูกส่งผิดจนกว่าจะล้างแคชเอง

Google ยังแสดงทั้งสองรูปแบบ

ต้องใช้เวลา ระหว่างนั้นให้ตรวจว่า canonical ในทุกหน้าชี้ไปรูปแบบหลัก และ Sitemap ระบุรูปแบบหลักด้วย

ต้องการให้ทีมงานช่วยตรวจสอบโครงสร้าง URL ของเว็บ ติดต่อ THAI DATA CLOUD ได้ที่ https://thaidata.cloud/contact/

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

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