GORAGOD.com

บทที่ 11 การใช้งาน AJAX กับภาษาไทย

เรื่องของภาษาไทย (รวมถึงภาษาอื่นๆ ที่ไม่ใช่ อังกฤษ) เนี่ยเป็นเรื่องปวดหัว สำหรับผู้เริ่มต้นใช้งาน AJAX ใหม่ๆ ครับ โดยทั่วไปแล้วการทดสอบว่า AJAX ของเราจะใช้ภาษาได้ถูกต้องหรือไม่ ก็ให้ลองเรียกหน้าที่ AJAX เรียกใช้ มาแสดงผลดู(โดยไม่ผ่านการเรียกใช้จาก AJAX) ว่ามันสามารถแสดงผลได้ถูกต้องหรือไม่ ถ้ามันสามารถแสดงผลได้ถูกต้อง แสดงว่าโค้ดของเราใช้ ภาษานั้นได้แน่ๆ (อย่างน้อยก็อ่านได้ละ....)

นอกจากนี้ เรื่องของภาษาเนี่ยยังอาจมีปัญหาอันเกิดจากความแตกต่างของ Server หรือ ความแตกต่างของ Browser ได้อีกด้วยซึ่งก็ทำให้เราจำเป็นต้องทดสอบกับ Server หลายๆแห่ง หรือ Browser หลายๆตัวด้วย

ขั้นตอนที่ 1 กำหนด header เพื่อกำหนดภาษา เป็นการกำหนด Header การเข้ารหัสเอกสารหน้าที่ถูก AJAX เรียกไป (PHP) ให้เป็นภาษาตามที่ต้องการครับ โดยให้เอาคำสั่งนี้ไว้ที่บรรทัดแรกสุดของไฟล์ PHP ถัดจาก <?php เลย
<?php
    header("content-type: application/x-javascript; charset=TIS-620");
จริงๆแล้วถ้าเป็นไปได้ ผมแนะนำให้ใช้ UTF-8 ครับ ปวดหัวน้อยกว่ากันเยอะเลย  โดยปกติแล้วหากเป็นการใช้ UTF-8 บรรทัดด้านบนอาจไม่ต้องกำหนดด้วยซ้ำไป และสำหรับการกำหนดเป็นภาษาอื่นๆ ให้แทนที่ TIS-620 ด้วยรหัสภาษาที่ต้องการ ครับ
ขั้นตอนที่ 2 กำหนด headerให้กับ AJAX (Javascript) ตอนส่งเพื่อบอกว่าเป็นการเข้ารหัส
// สร้าง connection
req.open("POST", "login.php");
// set Header
req.setRequestHeader("Content-Type", "application/x-www-form-urlencoded;");
// ส่ง
req.send("user="+encodeURIComponent(username)+
    "&passwd="+encodeURIComponent(passwd)+
    "&action="+action);

ขั้นตอนที่ 3 กำหนด ภาษาให้กับหน้าหลัก ทำได้ด้วยการแทรกโค้ด meta นี้ในส่วน <head>..</head> ของหน้าเพจหลัก (HTML)
<meta charset=TIS-620>

เหมือนเดิมครับ แทนที่ TIS-620 ด้วยรหัสภาษาที่ต้องการ อันนี้คงมีอยู่แล้วแหละ เพราะปกติถ้าไม่กำหนด เว็บก็จะอ่านไม่รู้เรื่องอยู่แล้ว และก็เช่นกัน ผมแนะนำให้ใช้ utf-8 มากกว่า
ขั้นตอนที่ 4 บันทึกไฟล์ทั้งหมดตามชนิดของรหัสภาษาที่ใช้ เช่น TIS-620 ให้ Save Page เป็น Ansi หรือถ้าเป็น UTF-8 ให้ Save File ให้เป็น UTF-8 ข้อนี้สำคัญมากนะครับหลายคนตกม้าตายที่ข้อนี้
ย้ำกันอีกครั้ง สำหรับมาตรฐานเว็บสมัยใหม่ ผมแนะนำให้ใช้ UTF-8 นะครับ เนื่องจาก UTF-8 จะรองรับเกือบทุกภาษาแล้ว ทำให้การออกแบบจะมีปัญหาน้อยมาก
ทั้งหมดที่กล่าวถึงเป็นเทคนิคเบื้องต้น ที่ต้องทำ เมื่อต้องการให้ AJAX แสดงผลถาษาไทยได้อย่างถูกต้องครับ ต่อไปเรามาดูเคล็ดลับเล็กๆน้อยๆ ในการทำเพื่อให้มันแสดงผลได้ตามต้องการ
// สร้าง connection
req.open("POST", "login.php");

การกำหนดชนิดของการส่งข้อมูล ผมแนะนำให้ใช้การส่งค่าแบบ GET สำหรับการใช้งานแบบ TIS-620 และใช้ POST สำหรับการใช้งานแบบ UTF-8 ครับ โดยกำหนดตอนสร้าง connection ด้วยฟังก์ชั่น open
และควรเข้ารหัสค่าที่ส่งด้วยฟังก์ชั่น encodeURIComponent() ก่อนส่งทั้ง POST หรือ GET เพื่อป้องกันตัวอักษรบางตัวหายเช่น & +
var query = "user=" + encodeURIComponent(username) +
    "&passwd=" + encodeURIComponent(passwd) +
    "&action=" + action;

สังเกตุนะครับว่า action ผมไม่ได้เข้ารหัสก่อน เนื่องจากตัวแปรนี้จะเก็บค่าเป็นภาษาอังกฤษเท่านั้นไม่มีอักขระที่อาจมีปัญหา (เนื่องจากเราสามารถควบคุมได้) ทำให้ไม่มีความจำเป็นต้องเข้ารหัส แตกต่างจาก username และ password ที่มาจากผุ้ใช้กรอก ซึ่งเราจะไม่ทราบเลยว่าผู้ใช้จะกรอกตัวอะไรมา

สำหรับเพจที่เป็น UTF-8 วิธีการทั้งหมดที่กล่าวมา ก็จะทำให้เพจสามารถทำงานกับ AJAX ได้อย่างสมบูรณ์แล้วครับ (ทุกภาษา) แต่สำหรับเพจที่เป็น TIS-620 (หรือภาษาอื่นๆ) เราอาจต้องทำการแปลงรหัสภาษา จาก UTF-8 ให้เป็น TIS-620(หรือภาษาที่ต้องการ) ก่อนด้วยฟังก์ชั่น iconv() ตอนรับค่าจาก AJAX เนื่องจาก AJAX ทำการส่งค่าด้วยรหัสภาษา UTF-8 ครับ

ตัวอย่างการใช้งานฟังก์ชั่น iconv()
$username = iconv('UTF-8' , 'TIS-620' , $_POST[username]);

สำหรับฟังก์ชั่น iconv() บาง Server อาจใช้ไม่ได้ เนื่องจากทาง Server อาจไม่เปิดให้ใช้งานฟังก์ชั่นในกลุ่มนี้ แต่เราก็สามารถเลี่ยงมาใช้ฟังก์ชั่นที่เขียนขึ้นเองเพื่อแปลงภาษาได้ครับ
function utf8_to_tis620($string)
{
    $str = $string;
    $res = "";
    for ($i = 0; $i < strlen($str); $i++) {
      if (ord($str[$i]) == 224) {
        $unicode = ord($str[$i+2]) & 0x3F;
        $unicode |= (ord($str[$i+1]) & 0x3F) << 6;
        $unicode |= (ord($str[$i]) & 0x0F) << 12;
        $res .= chr($unicode-0x0E00+0xA0);
        $i += 2;
      } else {
        $res .= $str[$i];
      }
    }
    return $res;
}

ตัวอย่างการใช้งาน
$username = utf8_to_tis620($_POST[username]);

ตัวอย่าง

ตัวอย่างการใช้งาน ฟังก์ชั่น utf8_to_tis620
<html>
<title>g-O-r-a-g-o-d.com [AJAX บทที่ 11]</title>
<head>
<!--Header หน้าหลัก-->
<meta charset=TIS-620>
<style>
body {
  font-family: Tahoma, MS Sans Serif;
  font-size: 8pt;
}
form {
  margin: 0px;
  padding: 0px;
{
</style>

</head>
<body>
<font color=red>คลิกขวา View Source เพื่อดูซอร์สโค้ด</font>
<br /><br />
ทดสอบโดยการพิมพ์ข้อความ เป็นภาษา อังกฤษ หรือ ไทย ลงในช่องกรอกข้อความ แล้วสังเกตุ ผลลัพท์
<br />(ผลลัพท์ถูกถอดรหัสด้วย utf8_to_tis620 ครับ ให้ลองสังเกตุเทียบกับบทที่ 4)
<form name=form1 action="" onsubmit="return false">
<input type=text name=txt value="test ทดสอบ">
<button onClick="sendget(form1.txt.value)">GET</button>
<button onClick="sendpost(form1.txt.value)">POST</button>
</form>
<br />
<div id=content>แสดงผล</div>
</body>
</html>
<script>
function Inint_AJAX() {
  try { return new ActiveXObject("Msxml2.XMLHTTP"); } catch(e) {}
  try { return new ActiveXObject("Microsoft.XMLHTTP"); } catch(e) {}
  try { return new XMLHttpRequest(); } catch(e) {}
  alert("XMLHttpRequest not supported");
  return null;
};

function sendget(value) {
  // สร้าง Object
  var req = Inint_AJAX();
  // กำหนด สถานะการทำงานของ AJAX แบบ GET และส่งข้อมูลผ่านทาง URL
  req.open('GET', 'test5.php?value=' + encodeURIComponent(value), true);
  // เหตุการณ์เมื่อมีการตอบกลับ
  req.onreadystatechange = function() {
    if (req.readyState==4) {
      if (req.status==200) {
       // ข้อความที่ได้มาจากการทำงานของ test5.php
      var data=req.responseText;
       // แสดงผล
      document.getElementById("content").innerHTML = "ข้อความที่ตอบกลับจาก server โดยการส่งแบบ GET คือ " + data;
      }
    }
  };
  // Header ตอนส่ง GET
  req.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
  // ทำการส่ง
  req.send(null);
};

function sendpost(value) {
  // สร้าง Object
  var req = Inint_AJAX();
  // กำหนด สถานะการทำงานของ AJAX แบบ POST
  req.open('POST', 'test5.php', true);
  // เหตุการณ์เมื่อมีการตอบกลับ
  req.onreadystatechange = function() {
    if (req.readyState==4) {
      if (req.status==200) {
       // ข้อความที่ได้มาจากการทำงานของ test5.php
      var data=req.responseText;
       // แสดงผล
      document.getElementById("content").innerHTML = "ข้อความที่ตอบกลับจาก server โดยการส่งแบบ POST คือ " + data;
      }
    }
  };
  // Header ตอนส่ง POST
  req.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
  // ทำการส่งข้อมูลผ่านคำสั่ง SEND
  req.send("value="+encodeURIComponent(value));
};
</script>

ไฟล์ test5.php ที่ถูกเรียก
<?php
  // กำหนด header ตอนรับ
  header("content-type: application/x-javascript; charset=TIS-620");
  // รับค่าที่ส่งมา
  $value=(isset($_POST["value])) ? $_POST["value] : $_GET["value];
  // แปลงจาก UTF8 ให้เป็น TIS-620
  function utf8_to_tis620($string) {
    $str = $string;
    $res = "";
    for ($i = 0; $i < strlen($str); $i++) {
      if (ord($str[$i]) == 224) {
        $unicode = ord($str[$i+2]) & 0x3F;
        $unicode = (ord($str[$i+1]) & 0x3F) << 6;
        $unicode = (ord($str[$i]) & 0x0F) << 12;
        $res .= chr($unicode-0x0E00+0xA0);
        $i += 2;
      } else {
        $res .= $str[$i];
      }
    }
    return $res;
  }
  // แปลงกลับข้อความเป็น TIS-620 และ แสดงผลสำหรับส่งกลับ
  echo utf8_to_tis620($value);