แก้ปัญหา Mixed Content หลังเปลี่ยนเว็บ WordPress เป็น HTTPS
หลังติดตั้ง SSL และเปลี่ยนเว็บ WordPress เป็น HTTPS หลายเว็บพบว่าแถบที่อยู่ของเบราว์เซอร์ไม่ขึ้นสถานะปลอดภัย บางเว็บรูปภาพหาย ฟอนต์ไม่โหลด หรือปุ่มบางปุ่มกดไม่ได้ สาเหตุคือ Mixed Content หมายถึงหน้าเว็บโหลดผ่าน https:// แต่ภายในหน้ายังเรียกไฟล์ย่อย เช่น รูป สคริปต์ หรือ CSS ผ่าน http://
เบราว์เซอร์แบ่ง Mixed Content เป็น 2 ประเภท ประเภทที่อันตรายน้อย เช่น รูป เสียง และวิดีโอ เบราว์เซอร์รุ่นใหม่จะพยายามเปลี่ยนเป็น HTTPS ให้เอง ถ้าไม่ได้ก็ไม่โหลด ส่วนประเภทที่อันตราย เช่น JavaScript, CSS และ iframe จะถูกบล็อกทันที ซึ่งทำให้หน้าเว็บพังได้ บทความนี้อธิบายวิธีหาต้นตอและแก้ให้หมดอย่างถาวร
สิ่งที่ต้องเตรียม
- SSL Certificate ติดตั้งแล้วและเปิด
https://example.comได้ หากยังไม่มี ดู ติดตั้ง SSL ฟรีจาก Let's Encrypt ด้วย Certbot บน Nginx หรือ ติดตั้ง SSL ฟรี Let's Encrypt บน DirectAdmin - บัญชี Administrator ของ WordPress และสิทธิ์ SSH พร้อม WP-CLI (แนะนำ)
- ไฟล์สำรองฐานข้อมูลก่อนแก้ไข
ขั้นตอนที่ 1: หาว่าไฟล์ไหนยังเป็น HTTP
ใช้ 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 ต้องเลิกใช้หรือหาบริการอื่นแทน
ขั้นตอนที่ 5: กรณีเว็บอยู่หลัง Cloudflare หรือ Reverse Proxy
ถ้า SSL จบที่ Cloudflare หรือ Load Balancer แล้วส่งต่อมาที่เซิร์ฟเวอร์ด้วย HTTP ฟังก์ชัน is_ssl() ของ WordPress จะเข้าใจว่าเป็น HTTP และสร้างลิงก์ไฟล์เป็น http:// หรือทำให้ Redirect วนซ้ำ วิธีที่ดีที่สุดคือใช้ HTTPS ตลอดเส้นทาง (Cloudflare โหมด Full (strict)) ดู เลือก SSL/TLS Mode บน Cloudflare ให้ถูกต้อง หากเลี่ยงไม่ได้ ให้เพิ่มใน wp-config.php ก่อนบรรทัด /* That's all, stop editing! */
if ( isset( $_SERVER['HTTP_X_FORWARDED_PROTO'] ) && $_SERVER['HTTP_X_FORWARDED_PROTO'] === 'https' ) {
$_SERVER['HTTPS'] = 'on';
}
ใช้โค้ดนี้เฉพาะเมื่อเซิร์ฟเวอร์รับการเชื่อมต่อจาก Proxy ที่เชื่อถือได้เท่านั้น เพราะผู้ใดก็ส่งหัว X-Forwarded-Proto มาเองได้
ขั้นตอนที่ 6: ตัวช่วยชั่วคราว upgrade-insecure-requests
ระหว่างที่ยังแก้ไม่ครบ สามารถสั่งให้เบราว์เซอร์เปลี่ยนคำขอ HTTP ภายในหน้าเป็น HTTPS อัตโนมัติด้วย Header นี้ บน Nginx
add_header Content-Security-Policy "upgrade-insecure-requests" always;
บน Apache (ต้องเปิด mod_headers)
Header always set Content-Security-Policy "upgrade-insecure-requests"
วิธีนี้ได้ผลเฉพาะไฟล์ที่มีเวอร์ชัน HTTPS อยู่แล้ว และไม่ได้แก้ข้อมูลจริง ควรใช้เป็นทางผ่านระหว่างทำขั้นตอนที่ 3 และ 4 ให้ครบ หากเว็บมี Content-Security-Policy อยู่แล้ว ให้เพิ่มคำสั่งนี้ลงในค่าเดิม ไม่ใช่เพิ่มหัวใหม่ซ้อน ดูเพิ่มเติมที่ ตั้งค่า HTTP Security Headers ให้เว็บไซต์
ตรวจสอบผลลัพธ์
- ล้าง Cache ของปลั๊กอิน Cache, CDN และเบราว์เซอร์ แล้วรัน
wp cache flush - เปิดหน้าเว็บหลายประเภท (หน้าแรก บทความ หน้าสินค้า หน้าติดต่อ) ด้วยแท็บ Console เปิดไว้ ต้องไม่มีข้อความ Mixed Content
- รันคำสั่ง
curlในขั้นตอนที่ 1 อีกครั้ง ต้องไม่พบลิงก์src="http:// - ค้นหาในฐานข้อมูล
wp db search 'http://example.com' --statsควรเหลือเฉพาะคอลัมน์ GUID
ปัญหาที่พบบ่อย
แก้ครบแล้วแต่ยังเห็น Mixed Content
หน้าที่เห็นอาจมาจาก Cache เก่า ทั้งปลั๊กอิน Cache, ไฟล์ CSS ที่รวมไฟล์ไว้ (Minify/Combine) และ CDN ให้ล้างทุกชั้นแล้วทดสอบใหม่ด้วยหน้าต่าง Incognito
Redirect วนซ้ำหลังเปลี่ยนเป็น HTTPS
มักเกิดจากตั้ง Cloudflare เป็นโหมด Flexible ร่วมกับการบังคับ HTTPS ที่เซิร์ฟเวอร์ ให้แก้ตามขั้นตอนที่ 5
รูปในบทความเก่ายังเป็น HTTP แม้รัน search-replace แล้ว
ตรวจว่ารันครบทุกรูปแบบของโดเมน (มีและไม่มี www) และปลั๊กอินที่เก็บข้อมูลในตารางของตัวเองต้องเพิ่ม --all-tables-with-prefix
หากทำตามขั้นตอนแล้วยังติดปัญหา สามารถติดต่อทีมสนับสนุนของ THAI DATA CLOUD ได้ที่ https://thaidata.cloud/contact/
- Categories:
- Cloud
- Tags:
- Cloud
- Cloud Server
Related Posts
หมวดหมู่ที่น่าสนใจ
- Account Settings
- AD Server
- AI
- Alibaba Cloud
- Anti-Spam Gateway
- AWS Amazon Web Services
- Campaign
- CentOS/AlmaLinux
- Cloud
- Cloud Backup
- Cloud Communication
- Cloud Migration
- Cloud Security
- Cloud Server Management
- Cloud Solution
- Cloud Solution for Government
- Cloud Solutions by Industry
- Cloud Storage
- Cloud VPS App Plus +
- Cloud VPS DirectAdmin
- Cloud VPS Plesk
- CSR
- Cyber Security
- Cybersecurity
- Data Sovereignty
- Database Server
- DDoS
- Digital Tranformation
- Digital Transformation
- Direct Mail
- Directadmin
- Domainname
- Ecommerce
- ERP
- Generative AI
- Getting Started
- Google Cloud
- Google G Suite
- Huawei Cloud
- IT News
- Linux Server
- Managed Cloud Services
- Managed Service Provider
- Manual
- Microsoft
- Microsoft 365
- Microsoft Azure
- News
- On-premise
- Private Mail Server
- Promotion
- Recommend Solution (Enterprise)
- Server
- Sovereign Cloud
- THAI DATA CLOUD Platform
- Ubuntu
- Ubuntu
- Uncategorized
- VMware
- VPS Server
- Web Design
- Web Hosting
- Web Hosting (DirectAdmin)
- Web Hosting (Plesk)
- Web Technologies
- Windows Server
- Wordpress
- Zimbra
- เรื่องราวความประทับใจ
- โซลูชันสำหรับธุรกิจการผลิตและยานยนต์
- โซลูชันสำหรับธุรกิจการศึกษา
- โซลูชันสำหรับธุรกิจการเงิน
- โซลูชันสำหรับธุรกิจขนส่งและกระจายสินค้า
- โซลูชันสำหรับธุรกิจค้าปลีก
- โซลูชันสำหรับธุรกิจท่องเที่ยว
- โซลูชันสำหรับธุรกิจบริการสุขภาพและโรงพยาบาล
- โซลูชันสำหรับธุรกิจประกันภัย
- โซลูชันสำหรับธุรกิจพลังงานและสาธารณูปโภค
- โซลูชันสำหรับธุรกิจสื่อสารมวลชนและเอ็นเตอร์เทนเมนท์
- โซลูชันสำหรับธุรกิจอสังหาริมทรัพย์
- โซลูชันสำหรับธุรกิจเทคโนโลยี


