แก้ไขปัญหา “Same Origin Restriction” ของ @font-face ใน Firefox และ IE9

ถ้า developer ใช้ Chrome และ Safari จะไม่มีปัญหาการโหลด @font-face จาก sub-domain หรือ domain ต่างกัน ทำให้เราสามารถใช้ผ่าน CDN จากเว็บผู้ผลิตหรือให้บริการ font-face ได้เช่น http://www.google.com/fonts หรือ http://fontawesome.io เป็นต้น

แต่ถ้าใช้ Firefox (รุ่นใหม่ๆ) และ IE9เป็นต้นมา จะมีปัญหา เนื่องจากข้อกำหนด Same Origin Restriction ตามเอกสาร CSS Fonts Module Level 3 (W3C Candidate Recommendation 3 October 2013) – Font fetching requirements ทำให้อาจเกิดปัญหาการโหลดตัว @font-face เข้ามาในเว็บได้ ซึ่งอาจทำให้เกิดการโหลดไม่ขึ้น หรือโหลดช้าจนทำให้การใช้งานเว็บไม่สะดวกได้ และคาดว่าในอนาคต Chrome และ Safari จะทำตามข้อกำหนดเช่นกัน

ตัวอย่างใน Firefox 26.0 ทีเกิดปัญหาโหลด icon จาก @font-face ไม่ได้ ทำให้ไม่แสดงผล icon ได้ถูกต้อง
(ถ้าเป็น IE9-10 จะไม่แสดงผลเลย)

2014-01-03_134524

ซึ่งใน developer console ของ Firefox จะมีการแจ้ง Error ว่า “bad URI  or cross-site access not allowed” ขึ้นมาด้วย

แต่เมื่อเปิดกับ Chrome และ Safari จะทำงานได้ปรกติ

2014-01-03_134645

ทางแก้ไขคือ ทำ Cross-Origin Resource Sharing ให้กับนามสกุลไฟล์ที่ใช้ในการทำ @font-face ต่างๆ ที่จะโหลดข้าม domain ซึ่งไฟล์ที่ใช้ทำ font-face จะมีนามสกุลต่อไปนี้ .ttf, .eot, .otf และ .woff

การแก้ไข

1. เปิดการใช้งาน mod_headers ใน Aapche เสียก่อน (ใครใช้ NginxX หาเอาอีกทีนะ)

2. แก้ไขไฟล์ .htaccess ใน root directory ของเว็บ แล้วเพิ่ม Type และ FilesMatch เพื่อเปิด Access-Control-Allow-Origin สำหรับไฟล์นามสกุลดังกล่าว โดยลักษณะการตั้งค่าตามด้านล่าง

AddType application/vnd.ms-fontobject    .eot
AddType application/x-font-opentype      .otf
AddType image/svg+xml                    .svg
AddType application/x-font-ttf           .ttf
AddType application/font-woff            .woff

<FilesMatch "\.(ttf|otf|eot|woff)$">
    <IfModule mod_headers.c>
        Header set Access-Control-Allow-Origin "*"
    </IfModule>
</FilesMatch>

เพียงเท่านี้ก็แก้ไขปํญหาทั้งหมดได้แล้ว ;)

ปรับ Adsense ให้รองรับหลายๆ ขนาดหน้าจอ (Responsive Design)

กระแส Responsive Design ที่ปรับหน้าของตัวเว็บให้เหมาะสมกับอุปกรณ์แต่ละแบบที่กำลังเข้าถึงหน้าเว็บนั้นๆ กำลังเป็นหัวข้อที่กำลังทำให้การออกแบบเว็บในปีนี้ แต่ปัญหาของเว็บจำนวนหนึ่งคือตัว Ads ในบางผู้ให้บริการไม่ได้ออกแบบมารองรับและปรับสภาพขนาดแต่อย่างใด ซึ่งเว็บผมก็เจออยู่คือ Adsense นั้นจะเป็นลักษณะความกว้างและสูงตายตัว ทำให้ลำบากต่อการปรับแต่ง

แต่หลังจากที่ได้ค้นหา ก็พบว่ามีคนใช้ Media Query ใน CSS3 มาช่วย แต่ปัญหาคือ การทำแบบนี้จะผิดข้อกำหนดของ Google ที่ไม่ยอมให้ Adsense นั้นอยู่ใน tag “display:none;” หรือหลบด้วยการเลื่อนตำแหน่งไปซ่อน ซึ่งผิด TOS เต็มๆ และยังมีผลทางเทคนิคในเรื่องของการโหลด JavaScript เกินความจำเป็นทำให้หน้าเว็บโหลดช้า

แต่ก็เจอทางออกจนได้จาก Google Approves Responsive AdSense Ads นั้นสามารถใช้โค้ดจาก How to use Google AdSense Ads on Responsive Websites ได้ ผมจึงนำมาปรับแต่งเล็กน้อยเพื่อให้เหมาะสมกับขนาดหน้าจอ 4 screen (960px, 800px, 480px และ 320px) ที่ Theme ของ Blog นี้ทำงานอยู่ ตามโค้ดด้านล่างนี้ คราวนี้ Ads ก็รองรับการทำงานควบคู่กับ Theme แบบ Responsive Design แล้วครับ

javascript

  1. <script type="text/javascript">
  2.    
  3.     var width = window.innerWidth
  4.       || document.documentElement.clientWidth
  5.       || document.body.clientWidth;
  6.  
  7.     google_ad_client = "ca-publisher-id";
  8.    
  9.     if (width > 800) {
  10.       // For 960px
  11.       google_ad_slot = "ad-unit-1";
  12.       google_ad_width = 728;
  13.       google_ad_height = 90;
  14.     } else if ((width < 800) && (width > 480)) {
  15.       // Load 800px
  16.       google_ad_slot = "ad-unit-2";
  17.       google_ad_width = 468;
  18.       google_ad_height = 60;
  19.     } else if ((width < 480) && (width > 320)) {
  20.       // For 480px
  21.       google_ad_slot = "ad-unit-3";
  22.       google_ad_width = 320;
  23.       google_ad_height = 50;
  24.     } else {              
  25.       // For 320px
  26.       google_ad_slot = "ad-unit-4";
  27.       google_ad_width = 234;
  28.       google_ad_height = 60;
  29.     }
  30.    
  31. </script>
  32. <script type="text/javascript"
  33. src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
  34. </script>