กลับสู่บล็อก
เทคโนโลยี

รูปแปะเว็บอื่นแล้วแตก? ผังแก้ 403 กับ hotlink protection ฉบับสมบูรณ์ 2026

เผยแพร่เมื่อ5 min read
แชร์

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

หลุมนี้ผมเหยียบมาไม่ใช่ครั้งเดียว มีอยู่ครั้งที่พังออนไลน์คือช่วยเพื่อนย้ายรูปในฟอรั่ม ในเครื่องเขียวหมด ขึ้นเว็บแล้วภาพย่อหน้าแรกแตกไปหนึ่งในสาม ตอนนั้นยังนึกว่าแคชไม่ได้ล้าง ดีบักสามวันถึงพบว่าไม่ใช่ปัญหาผมเลย — เป็นเพราะเว็บต้นทางรูปเปิด hotlink protection ขอแค่คำขอไม่ได้มาจากโดเมนตัวเอง บล็อกหมด

มองจากมุมสถาปัตยกรรม "รูปแสดงไม่ได้บนเว็บอื่น" จริงๆ คือความล้มเหลวสามแบบที่ต่างกันสิ้นเชิงถูกเอามาปนกันพูด จะแก้ให้ถูก ขั้นแรกต้องแยกก่อนว่าคุณเจอแบบไหน

แยกก่อน: 403, รูปแตก, 200 ว่างเปล่า เป็นคนละเรื่อง

หลายคนพอเห็นรูปหายก็เหมารวมว่า "รูปแตก" แล้วลองมั่วไปทั่ว จริง ๆ แล้วสามอาการนี้ต้นตอห่างกันมาก เส้นทางแก้ก็ไม่เหมือนกัน

อาการ รหัส HTTP ต้นตอที่น่าจะเป็น ทิศทางแก้
กรอบไอคอนแตก (ไอคอนฉีก) 403 / 404 hotlink บล็อก หรือลิงก์เองผิด เช็ก Referer กับความถูกของ url
กรอบไอคอนแตก (ไอคอนฉีก) 200 แต่ไม่ใช่รูป ได้หน้า HTML error ไม่ใช่ไฟล์รูป เช็ก Content-Type
ว่างเปล่า (ไม่มีไอคอนฉีก) 200 CSS บัง หรือ CSP กันโหลด เช็ก DevTools Console กับ CSP
ไอคอนหมุนแล้วหาย timeout / CORS นโยบายข้ามโดเมนหรือเซิร์ฟเวอร์ timeout เช็กรายละเอียด request ใน Network

ดูรหัสสถานะก่อน แล้วดู Content-Type สุดท้ายค่อยดูหน้าจอ ลำดับนี้กลับด้านเมื่อไรจะวนหัวชนกำแพง

หลักการชั้นล่าง: Referer กับ hotlink ทำงานยังไง

จะเข้าใจว่าทำไมรูปเว็บอื่นโดนบล็อก ต้องรู้ก่อนว่าเบราว์เซอร์แอบทำอะไรตอนโหลดรูป

เมื่อหน้า A ใช้ <img src="https://B.com/photo.jpg"> ไปโหลดรูปเว็บ B คำขอที่เบราว์เซอร์ส่งจะแนบเฮดเดอร์ Referer (ใช่ คำนี้ในประวัติศาสตร์สะกดผิด ขาด r ตัวหนึ่ง แล้วผิดต่อมาถึงทุกวันนี้) เฮดเดอร์นี้บอกเว็บ B ว่า "รูปนี้ถูกร้องขอโดยหน้าเว็บ A"

หลักการชั้นล่างเป็นแบบนี้: เซิร์ฟเวอร์หรือ CDN ของเว็บ B พอรับคำขอ จะเอาโดเมนใน Referer ไปเทียบกับ whitelist ตรรกะการเทียบประมาณนี้ —

1. Referer ว่าง (เปิดรูปตรง, บุ๊กมาร์ก) → ดูการตั้งค่าว่าปล่อยหรือบล็อก
2. โดเมนของ Referer อยู่ใน whitelist → ปล่อย
3. โดเมนของ Referer ไม่อยู่ใน whitelist → ตอบ 403 Forbidden

นี่แหละ hotlink protection จุดประสงค์มันเรียบง่าย: ไม่อยากให้คนอื่นมากินแบนด์วิดท์ฟรี คุณเอารูปเว็บ B ไปฝังบนเว็บตัวเอง ทุกครั้งที่คนอื่นเปิดหน้าคุณ บิลทราฟฟิกไปตกที่เว็บ B เว็บ B ไม่พอใจอยู่แล้ว

ตรงนี้มีรายละเอียดที่หลายคนไม่รู้: Referrer-Policy เริ่มต้นของเบราว์เซอร์สมัยใหม่คือ strict-origin-when-cross-origin เวลาคำขอข้ามโดเมน มันส่งแค่ "โดเมนต้นทาง" (เช่น https://a.com/) ไม่ส่งพาธเต็ม hotlink เลยได้ชื่อโดเมนคุณ พอเทียบ whitelist และพอบล็อกคุณ นี่คือเหตุที่ hotlink จัดการ hotlink ได้

ทำไมรูปคุณแตกบนเว็บอื่น: ผังแก้ปัญหาหนึ่งต้น

กางหลักการข้างบนออก ต้นตอรูปแตกจริงๆ ยุบเหลือต้นไม้ต้นเดียว เดินตามลงไปได้เลย

กิ่งที่ 1: รหัสสถานะเป็น 403 ไหม?

ถ้าใช่ เก้าสิบเปอร์เซ็นต์คือ hotlink เว็บ B เห็น Referer คุณไม่อยู่ใน whitelist ปฏิเสธเลย กรณีนี้คุณแก้การตั้งค่าเว็บ B ไม่ได้ ทางแก้เดียวคือเลิก hotlink รูปมัน (จะพูดทางแก้ที่ถูกทีหลัง)

กิ่งที่ 2: รหัส 200 แต่หน้าจอรูปแตก?

เปิดดูเนื้อหาดิบของ "รูป" นี้ เป็นไปได้สูงว่าคุณได้หน้า HTML — บางเว็บไม่ตอบ 403 แต่ตอบหน้า "ห้ามลิงก์ตรง" รหัสยังเป็น 200 เบราว์เซอร์เอา HTML มาแปลเป็นรูป ก็ฉีกให้ดูสิ เช็ก Content-Type ก็รู้: รูปปกติเป็น image/jpeg, image/png หน้า error จะเป็น text/html

กิ่งที่ 3: คุณแปะ "ลิงก์หน้า" ไม่ใช่ "ลิงก์รูปตรง"?

นี่คือกับดักที่มือใหม่เจอบ่อยสุด https://imgur.com/aBcDeFg เป็นหน้าเว็บ ส่วน https://i.imgur.com/aBcDeFg.jpg ต่างหากคือตัวไฟล์รูป อันแรกคุณเอาไปใส่ <img src> จะได้หน้า HTML ทั้งหน้า ไม่ใช่รูป ต่างกันแค่ i. กับนามสกุลไฟล์ ผลลัพธ์ห่างฟ้ากับดิน

กิ่งที่ 4: Referrer-Policy ทำร้ายตัวคุณเอง?

แบบที่แอบซ่อนหน่อย ถ้าหน้าคุณตั้ง Referrer-Policy: no-referrer เบราว์เซอร์ตอนโหลดรูปจะไม่ส่ง Referer เลย hotlink บางการตั้งค่าคือ "Referer ว่างบล็อกหมด" คุณเลยโดนการตั้งค่าความเป็นส่วนตัวของตัวเองกันไว้นอกประตู จากที่ผมลอง เคสนี้มักเกิดกับเว็บที่แคร์ความเป็นส่วนตัวมาก ปิด meta referrer สนิท

ลงมือวินิจฉัย: DevTools กับ curl สองไม้ตาย

ทฤษฎีจบแล้ว จริงๆ เช็กยังไง ผมใช้สองเครื่องมือประจำ หาต้นตอ 90% ได้ในห้านาที

ไม้แรก: แผง DevTools Network

เปิด developer tools ของเบราว์เซอร์ (F12) สลับไป Network รีเฟรชหน้า พิมพ์ชื่อไฟล์รูปในช่องกรอง กดเข้าคำขอนั้น ดูสามอย่าง:

  • Status: เป็น 403, 404 หรือ 200?
  • Content-Type ใน Response Headers: เป็น image/* หรือ text/html?
  • Referer ใน Request Headers: ที่ส่งออกไปจริงคืออะไร ว่างหรือโดเมนคุณ?

ดูครบสาม ต้นตอก็โผล่มาแล้ว

ไม้สอง: curl คุม Referer ด้วยมือ

DevTools เห็นปรากฏการณ์ แต่จะยืนยันว่า "ใช่ hotlink ไหม" curl ตรงสุด คุณยัด Referer อะไรก็ได้ ดูว่าเซิร์ฟเวอร์ตอบต่างกันยังไง:

# ไม่แนบ Referer เลย (จำลองเปิดรูปตรง)
curl -I "https://example.com/photo.jpg"

# แนบ Referer "ปลอมเป็นมาจากเว็บต้นทางเอง"
curl -I -H "Referer: https://example.com/" "https://example.com/photo.jpg"

# แนบ Referer "มาจากเว็บนอกของคุณ"
curl -I -H "Referer: https://your-blog.com/" "https://example.com/photo.jpg"

อ่านผลง่ายมาก ถ้าอันที่หนึ่งกับสามตอบ 403 แต่อันที่สองตอบ 200 — ยินดีด้วย จับได้คาหนังคาเขาว่าเป็น hotlink เซิร์ฟเวอร์รับแค่ Referer ของเว็บต้นทางเอง ที่เหลือบล็อกหมด ถ้าสามอันตอบ 200 หมด รูปแตกก็ไม่เกี่ยว hotlink ย้อนไปเช็ก url หรือ CSP ของคุณ

ผมชอบรันสามเส้นพร้อมกัน เทียบผลชัดกว่าดูเส้นเดียวเยอะ นี่แหละที่ curl มีประสิทธิภาพกว่ากดมั่วในเบราว์เซอร์

พฤติกรรม hotlink ของเว็บฝากรูป / CDN ที่พบบ่อย

นิสัยเริ่มต้นของแต่ละบริการต่างกันมาก ข้างล่างคือสิ่งที่ผมสังเกตจากการย้ายรูปมาหลายปี การตั้งค่าจริงแต่ละเจ้าปรับได้ตลอด แต่ทิศทางใหญ่เป็นแบบนี้

ประเภทบริการ เริ่มต้นกัน hotlink? พฤติกรรม Referer ว่าง เหมาะลิงก์ตรงจากเว็บนอก?
Nginx / Apache ตั้งเอง แล้วแต่ตั้ง มักปล่อย แล้วแต่ตั้ง
CDN ระดับองค์กร (ตั้ง whitelist ได้) เปิดปิดได้ ตั้งปล่อยหรือบล็อกได้ ตั้งถูกก็ได้
เว็บฝากรูปฟรีบางเจ้า มักเปิด มักบล็อก มักโดนบล็อก
โดเมนรูปของโซเชียล เปิดแทบทั้งหมด บล็อกแทบทั้งหมด ไม่ได้ อย่าคิด
เว็บฝากรูปที่เน้นแชร์ มักปิด ปล่อย ได้ นี่แหละความหมายที่มันมีอยู่

จุดสำคัญคือแถวสุดท้าย รูปจากโซเชียล (โดเมน CDN ของเว็บโซเชียลพวกนั้น) url ที่คุณก็อปออกมาแทบร้อยเปอร์เซ็นต์ลิงก์นอกไม่ได้ เพราะโมเดลธุรกิจมันคือล็อกคุณไว้ในเว็บ อยากเอารูปพวกนั้นไปแปะที่อื่น ตายทางเดียว

ส่วนเว็บฝากรูปที่เน้น "แชร์" กัน hotlink เริ่มต้นคือปิด — ความหมายที่มันมีอยู่คือให้รูปคุณถูกโหลดจากเว็บนอกได้เสถียร สองประเภทนี้อย่าเอามาสับสน

กับดัก Referrer-Policy: แม้แต่เบราว์เซอร์ก็อาจย้อนทำร้ายคุณ

ข้างบนพูดถึงสถานการณ์แอบซ่อนแบบหนึ่ง ตรงนี้ขอกางเพราะมันทำให้คนดีบักจนคิดมาก

Referrer-Policy เป็นเฮดเดอร์ที่หน้า (ฝ่ายที่ส่งคำขอ) ตั้งได้ มันตัดสินว่าเบราว์เซอร์จะส่งข้อมูล Referer มากแค่ไหน ค่ามีหลายแบบ:

  • no-referrer: ไม่ส่งเลย
  • origin: ส่งแค่โดเมนต้นทาง
  • strict-origin-when-cross-origin: ข้ามโดเมนส่งแค่โดเมน ลดเป็น HTTP ก็ไม่ส่ง (ค่าเริ่มต้นสมัยใหม่)
  • unsafe-url: ส่งพาธเต็มด้วย (ไม่แนะนำ รั่วความเป็นส่วนตัว)

จุดขัดแย้งอยู่ตรงนี้ hotlink ต้องพึ่ง Referer ตัดสินต้นทาง แต่นโยบายความเป็นส่วนตัวกลับส่งเสริมให้ส่งน้อยหรือไม่ส่ง Referer พอเว็บหนึ่งตั้ง no-referrer เพราะความเป็นส่วนตัว มันไปโหลดรูปที่มี hotlink แบบ "Referer ว่างบล็อกหมด" ก็แตกยกแผง

ผมเคยพังออนไลน์แบบนี้ครั้งหนึ่ง — เว็บที่แคร์ความเป็นส่วนตัวมาก ทั้งเว็บใส่ no-referrer ผลคือรูปลิงก์นอกแตกหมด ตอนนั้นยังนึกว่าเว็บฝากรูปล่ม เช็กตั้งนานถึงพบว่าเป็น meta setting ตัวเองที่บีบ Referer ตาย กับดักนี้นึกถึงยาก เพราะ "เพิ่มความเป็นส่วนตัว" มันจะไปทำร้ายตัวเองได้ยังไง

วิธีที่ถูก: อย่า hotlink รูปคนอื่น

แก้ปัญหาไปจนสุด คุณจะเจอความจริงโหดร้ายข้อหนึ่ง: ตราบใดที่รูปไม่ได้อยู่ในมือคุณเอง "รูปเว็บอื่น" ทุกใบอาจหายไปในจังหวะที่คุณคุมไม่ได้ อีกฝ่ายเปลี่ยน hotlink เปลี่ยน url ลบไฟล์ หรือปิดทั้งเว็บ หน้าคุณก็แตกตาม

วิธีที่เสถียรจริงมีแค่สองทาง

หนึ่ง เอารูปมาฝากใหม่ในที่ที่คุณคุมได้ อย่าฝัง url คนอื่นตรงๆ โหลดรูปลงมา อัปขึ้นพื้นที่ตัวเองหรือเว็บฝากรูปที่อนุญาตลิงก์นอก แล้วเปลี่ยนไปใช้ url เสถียรนั้น มองจากมุมสถาปัตยกรรม ขั้นนี้แก่นคือเอาความพร้อมใช้ของหน้าคุณจากมือเซิร์ฟเวอร์คนอื่นกลับมาไว้ในมือตัวเอง — ตราบใดที่ต้นทางไม่ใช่สิ่งที่คุณคุมได้ การปรับ hotlink ของอีกฝ่าย การเปลี่ยนโครงสร้าง url หรือแม้แต่การปิดเว็บ ล้วนสะท้อนตรงมาเป็นรูปแตกบนหน้าคุณ แถมคุณไม่ได้รับการเตือนล่วงหน้า มักรู้ตอนคนอ่านมาแจ้งว่าพังแล้ว ถ้าในมือคุณมีลิงก์เก่ากระจายอยู่ในโดเมนคนอื่นเป็นชุดใหญ่ที่ต้องย้ายทีเดียว ผมเขียน SOP เปลี่ยนลิงก์รูปเป็นชุดฉบับสมบูรณ์ ไว้ ใช้สคริปต์กวาด url เก่าทั้งเว็บเปลี่ยนทีเดียว สบายกว่าเปลี่ยนทีละใบเยอะ ต้นทางที่คุมได้เท่านั้นถึงเป็นต้นทางที่เสถียร

สอง เลือกเว็บฝากรูปที่กัน hotlink เริ่มต้นเป็นปิด เว็บฝากรูปฟรีหลายเจ้าเพื่อประหยัดแบนด์วิดท์จะบล็อกลิงก์นอก แปะฟอรั่มหรือบล็อกก็แตกให้ดู อยากลิงก์นอกก็เลือกบริการที่อนุญาตลิงก์ตรงชัดเจน

นี่ก็เป็นหลักการหนึ่งของเราตอนทำ lpic.cc: อัปแล้วให้ url ลิงก์รูปตรงเสถียร ไม่ตั้งบล็อกเว็บนอก ให้คุณแปะลงฟอรั่ม บล็อก Discord แสดงได้ปกติ ไม่กลายเป็น 403 แบบงงๆ รูปที่ต้องการส่วนตัวก็ตั้งรหัสผ่านคุมว่าใครเห็นได้ อยากลอง อัปโหลดฟรี รูปหนึ่ง เอาลิงก์ไปแปะหน้าอื่นเทสต์ก็รู้เลยว่าเสถียรไหม

พูดตรงๆ ต้องบอกข้อจำกัดด้วย: แผนฟรีตอนนี้รูปมีอายุเก็บ 30 วัน ไม่ใช่เก็บถาวร และบริการอยู่ได้ด้วยรายได้โฆษณา เก็บถาวรระยะยาวหรือคลังรูปเชิงพาณิชย์จำนวนมาก คุณควรพิจารณาแผนโปรแบบเสียเงิน หรือตั้งสตอเรจที่มีแบ็กอัปเอง เลือกเครื่องมือให้ตรงสถานการณ์ถึงจะมีความหมาย — จุดนี้ผมเหยียบกับดักมาแล้วถึงเข็ด

คำถามที่พบบ่อย FAQ

Q: ทำไมลิงก์รูปเดียวกัน ผมเปิดเองได้ แปะเว็บอื่นแล้วแตก?

เพราะตอน "เปิดรูปตรง" Referer ว่างหรือมาจากต้นทางที่อนุญาต hotlink ปล่อยผ่าน แปะเว็บอื่นแล้ว Referer กลายเป็นโดเมนภายนอกนั้น ไม่อยู่ใน whitelist ก็โดนบล็อกเป็น 403 url เดียวกัน Referer ต่างกัน ผลต่างกันสิ้นเชิง

Q: 403 กับรูปแตกเป็นเรื่องเดียวกันไหม?

ไม่ใช่ 403 คือเซิร์ฟเวอร์ปฏิเสธชัดเจน (รหัส 403) รูปแตกเป็นแค่ภาพที่เบราว์เซอร์ "วาดรูปไม่ออก" 403 ทำให้รูปแตกได้ แต่รูปแตกก็มาจาก url ผิด Content-Type ผิด CSP กันโหลด สาเหตุอื่นได้ ดูรหัสสถานะก่อนถึงรู้ว่าเป็นแบบไหน

Q: ตั้งหน้าเป็น Referrer-Policy: no-referrer เลี่ยง hotlink ได้ไหม?

บางทีได้ บางทียิ่งหนัก ถ้า hotlink ของอีกฝ่ายเป็น "Referer ว่างปล่อย" ไม่ส่ง Referer ก็ผ่านจริง แต่ถ้าเป็น "Referer ว่างบล็อกหมด" คุณกลับแตกทั้งหมด ไม้นี้ไม่น่าเชื่อถือ อย่าใช้เป็นทางแก้จริง

Q: ผมใช้โปรแกรม (Python / Node) ดึงรูปก็โดน 403 ทำไงดี?

หลักการเดียวกับเบราว์เซอร์ — โปรแกรมคุณไม่ได้แนบ Referer ที่ถูก ใช้ curl เทสต์ก่อนว่าอีกฝ่ายรับ Referer ไหน แล้วเติมเฮดเดอร์เดียวกันในคำขอ HTTP ของคุณ แต่ระวัง: การเลี่ยง hotlink คนอื่นไปดึงรูปอาจผิดข้อกำหนดบริการของอีกฝ่าย พิจารณาเอง

Q: เช็กเร็วๆ ว่าเว็บฝากรูปลิงก์นอกได้ไหมยังไง?

อัปรูปทดสอบใบหนึ่ง เอา url ลิงก์ตรงมัน รัน curl -I -H "Referer: https://google.com/" ดู ตอบ 200 คืออนุญาตลิงก์นอก ตอบ 403 คือมี hotlink อย่าเอาไปแปะเว็บนอก สามสิบวินาทีเช็กจบ

อ้างอิง

#hotlink protection#กันลิงก์ตรง#403 Forbidden#Referer#Referrer-Policy#CDN#ลิงก์รูปตรง
H

เขียนโดย

Harvey Zhang

ผู้ร่วมก่อตั้ง & CTO

วิศวกร Backend และสถาปนิกระบบ