คำตอบสั้น ๆ: หาไฟล์ที่ยังโหลดผ่าน HTTP ด้วย Developer Tools แล้วแก้ Mixed Content ใน WordPress ให้หมด ทั้งในฐานข้อมูล ไฟล์ธีม และกรณีใช้ Cloudflare
คู่มือนี้อธิบาย Mixed Content ทีละขั้นตอน พร้อมคำสั่งที่ใช้ได้จริงและปัญหาที่พบบ่อย
หลังติดตั้ง SSL และเปลี่ยนเว็บ WordPress เป็น HTTPS หลายเว็บพบว่าแถบที่อยู่ของเบราว์เซอร์ไม่ขึ้นสถานะปลอดภัย บางเว็บรูปภาพหาย ฟอนต์ไม่โหลด หรือปุ่มบางปุ่มกดไม่ได้ สาเหตุคือ Mixed Content หมายถึงหน้าเว็บโหลดผ่าน https:// แต่ภายในหน้ายังเรียกไฟล์ย่อย เช่น รูป สคริปต์ หรือ CSS ผ่าน http://
เบราว์เซอร์แบ่ง Mixed Content เป็น 2 ประเภท ประเภทที่อันตรายน้อย เช่น รูป เสียง และวิดีโอ เบราว์เซอร์รุ่นใหม่จะพยายามเปลี่ยนเป็น HTTPS ให้เอง ถ้าไม่ได้ก็ไม่โหลด ส่วนประเภทที่อันตราย เช่น JavaScript, CSS และ iframe จะถูกบล็อกทันที ซึ่งทำให้หน้าเว็บพังได้ บทความนี้อธิบายวิธีหาต้นตอและแก้ให้หมดอย่างถาวร
สิ่งที่ต้องเตรียม (Mixed Content)
- SSL Certificate ติดตั้งแล้วและเปิด
https://example.comได้ หากยังไม่มี ดู ติดตั้ง SSL ฟรีจาก Let's Encrypt ด้วย Certbot บน Nginx หรือ ติดตั้ง SSL ฟรี Let's Encrypt บน DirectAdmin - บัญชี Administrator ของ WordPress และสิทธิ์ SSH พร้อม WP-CLI (แนะนำ)
- ไฟล์สำรองฐานข้อมูลก่อนแก้ไข
ขั้นตอนที่ 1: หาว่าไฟล์ไหนยังเป็น HTTP (Mixed Content)
ใช้ Developer Tools ของเบราว์เซอร์
- เปิดหน้าที่มีปัญหาด้วย Chrome, Edge หรือ Firefox
- กด
F12(macOS กดCmd + Option + I) แล้วเลือกแท็บ Console - โหลดหน้าใหม่ จะเห็นข้อความลักษณะนี้
Mixed Content: The page at 'https://example.com/' was loaded over HTTPS,
but requested an insecure script 'http://example.com/wp-content/plugins/slider/js/app.js'.
This request has been blocked; the content must be served over HTTPS.
URL ที่อยู่ท้ายข้อความคือไฟล์ต้นเหตุ ให้จดไว้ทั้งหมด และสังเกตโดเมนของไฟล์ ว่าเป็นโดเมนของเราเองหรือโดเมนภายนอก
ใช้คำสั่งค้นหาจาก Command Line
curl -s https://example.com/ | grep -Eo '(src|href)="http://[^"]+"' | sort -u
คำสั่งนี้แสดงลิงก์ src และ href ที่ยังเป็น HTTP ในหน้าแรก (ลิงก์ href ไปหน้าอื่นไม่นับเป็น Mixed Content แต่ควรแก้ไปพร้อมกัน) ข้อจำกัดคือไม่เห็นไฟล์ที่ถูกเรียกจาก CSS หรือ JavaScript ภายหลัง จึงควรตรวจด้วย Developer Tools ควบคู่
ขั้นตอนที่ 2: แก้ URL หลักของเว็บ
ตรวจว่า home และ siteurl เป็น HTTPS แล้ว
wp option get home
wp option get siteurl
หากยังเป็น http:// ให้แก้ที่ Settings > General หรือด้วย wp option update ตามวิธีใน เปลี่ยน URL เว็บไซต์ WordPress
ขั้นตอนที่ 3: แทนที่ URL แบบ HTTP ในฐานข้อมูล
บทความและรูปที่อัปโหลดก่อนเปลี่ยนเป็น HTTPS ยังเก็บ URL แบบเก่าในฐานข้อมูล สำรองแล้วแทนที่ด้วย WP-CLI
wp db export ~/before-https.sql
wp search-replace 'http://example.com' 'https://example.com' --skip-columns=guid --dry-run
ตรวจตัวเลขในบรรทัดสรุป แล้วรันจริงโดยตัด --dry-run ออก หากเว็บเคยใช้ www ให้รันซ้ำกับ 'http://www.example.com' ด้วย และหากใช้ Page Builder ที่เก็บ URL แบบ Escape ให้รันกับ 'http:\/\/example.com' อีกครั้ง
wp search-replace 'http:\/\/example.com' 'https:\/\/example.com' --skip-columns=guid
ผู้ที่ใช้ Elementor มีเครื่องมือในตัวที่เมนู Elementor > Tools > Replace URL (ตำแหน่งอาจต่างกันตามเวอร์ชัน) และหลังเปลี่ยนให้กด Regenerate Files & Data ในหน้าเดียวกัน เพื่อสร้างไฟล์ CSS ใหม่ที่ไม่มี URL แบบ HTTP
หากไม่มี SSH ใช้ปลั๊กอิน Better Search Replace แทนได้ ห้ามใช้ SQL REPLACE() กับทั้งตาราง เพราะจะทำให้ข้อมูลแบบ Serialized เสีย
ขั้นตอนที่ 4: แก้ URL ที่ฝังอยู่ในไฟล์ธีมและปลั๊กอิน
หาก Console ยังแจ้งไฟล์ที่เป็นของเว็บเราเอง ต้นเหตุมักอยู่ในไฟล์ธีม เช่น header.php หรือไฟล์ CSS
cd /var/www/example.com
grep -rn "http://example.com" wp-content/themes/ wp-content/plugins/ --include=*.php --include=*.css --include=*.js
แก้ไฟล์ที่พบให้เป็น https:// หรือใช้ฟังก์ชันของ WordPress แทนการพิมพ์ URL ตรง เช่น get_template_directory_uri() หากไฟล์อยู่ในธีมหลัก การแก้จะถูกเขียนทับเมื่ออัปเดตธีม ควรแก้ผ่าน Child Theme หรือแจ้งผู้พัฒนาธีม
ไฟล์จากโดเมนภายนอก
หากไฟล์มาจากโดเมนภายนอก เช่น สคริปต์ของบริการเก่า ให้ลองเปิด URL เดียวกันด้วย https:// ถ้าเปิดได้ให้แก้ลิงก์เป็น HTTPS ถ้าเปิดไม่ได้ แปลว่าบริการนั้นไม่รองรับ HTTPS ต้องเลิกใช้หรือหาบริการอื่นแทน