บทที่ 11 การใช้งาน AJAX กับภาษาไทย
เรื่องของภาษาไทย (รวมถึงภาษาอื่นๆ ที่ไม่ใช่ อังกฤษ) เนี่ยเป็นเรื่องปวดหัว สำหรับผู้เริ่มต้นใช้งาน AJAX ใหม่ๆ ครับ โดยทั่วไปแล้วการทดสอบว่า AJAX ของเราจะใช้ภาษาได้ถูกต้องหรือไม่ ก็ให้ลองเรียกหน้าที่ AJAX เรียกใช้ มาแสดงผลดู(โดยไม่ผ่านการเรียกใช้จาก AJAX) ว่ามันสามารถแสดงผลได้ถูกต้องหรือไม่ ถ้ามันสามารถแสดงผลได้ถูกต้อง แสดงว่าโค้ดของเราใช้ ภาษานั้นได้แน่ๆ (อย่างน้อยก็อ่านได้ละ....)
นอกจากนี้ เรื่องของภาษาเนี่ยยังอาจมีปัญหาอันเกิดจากความแตกต่างของ Server หรือ ความแตกต่างของ Browser ได้อีกด้วยซึ่งก็ทำให้เราจำเป็นต้องทดสอบกับ Server หลายๆแห่ง หรือ Browser หลายๆตัวด้วย
ขั้นตอนที่ 1 กำหนด header เพื่อกำหนดภาษา เป็นการกำหนด Header การเข้ารหัสเอกสารหน้าที่ถูก AJAX เรียกไป (PHP) ให้เป็นภาษาตามที่ต้องการครับ โดยให้เอาคำสั่งนี้ไว้ที่บรรทัดแรกสุดของไฟล์ PHP ถัดจาก <?php เลย
ขั้นตอนที่ 3 กำหนด ภาษาให้กับหน้าหลัก ทำได้ด้วยการแทรกโค้ด meta นี้ในส่วน <head>..</head> ของหน้าเพจหลัก (HTML)
เหมือนเดิมครับ แทนที่ TIS-620 ด้วยรหัสภาษาที่ต้องการ อันนี้คงมีอยู่แล้วแหละ เพราะปกติถ้าไม่กำหนด เว็บก็จะอ่านไม่รู้เรื่องอยู่แล้ว และก็เช่นกัน ผมแนะนำให้ใช้ utf-8 มากกว่า
ขั้นตอนที่ 4 บันทึกไฟล์ทั้งหมดตามชนิดของรหัสภาษาที่ใช้ เช่น TIS-620 ให้ Save Page เป็น Ansi หรือถ้าเป็น UTF-8 ให้ Save File ให้เป็น UTF-8 ข้อนี้สำคัญมากนะครับหลายคนตกม้าตายที่ข้อนี้
การกำหนดชนิดของการส่งข้อมูล ผมแนะนำให้ใช้การส่งค่าแบบ GET สำหรับการใช้งานแบบ TIS-620 และใช้ POST สำหรับการใช้งานแบบ UTF-8 ครับ โดยกำหนดตอนสร้าง connection ด้วยฟังก์ชั่น open
และควรเข้ารหัสค่าที่ส่งด้วยฟังก์ชั่น encodeURIComponent() ก่อนส่งทั้ง POST หรือ GET เพื่อป้องกันตัวอักษรบางตัวหายเช่น & +
สังเกตุนะครับว่า action ผมไม่ได้เข้ารหัสก่อน เนื่องจากตัวแปรนี้จะเก็บค่าเป็นภาษาอังกฤษเท่านั้นไม่มีอักขระที่อาจมีปัญหา (เนื่องจากเราสามารถควบคุมได้) ทำให้ไม่มีความจำเป็นต้องเข้ารหัส แตกต่างจาก username และ password ที่มาจากผุ้ใช้กรอก ซึ่งเราจะไม่ทราบเลยว่าผู้ใช้จะกรอกตัวอะไรมา
สำหรับเพจที่เป็น UTF-8 วิธีการทั้งหมดที่กล่าวมา ก็จะทำให้เพจสามารถทำงานกับ AJAX ได้อย่างสมบูรณ์แล้วครับ (ทุกภาษา) แต่สำหรับเพจที่เป็น TIS-620 (หรือภาษาอื่นๆ) เราอาจต้องทำการแปลงรหัสภาษา จาก UTF-8 ให้เป็น TIS-620(หรือภาษาที่ต้องการ) ก่อนด้วยฟังก์ชั่น iconv() ตอนรับค่าจาก AJAX เนื่องจาก AJAX ทำการส่งค่าด้วยรหัสภาษา UTF-8 ครับ
ตัวอย่างการใช้งานฟังก์ชั่น iconv()
สำหรับฟังก์ชั่น iconv() บาง Server อาจใช้ไม่ได้ เนื่องจากทาง Server อาจไม่เปิดให้ใช้งานฟังก์ชั่นในกลุ่มนี้ แต่เราก็สามารถเลี่ยงมาใช้ฟังก์ชั่นที่เขียนขึ้นเองเพื่อแปลงภาษาได้ครับ
ตัวอย่างการใช้งาน
ตัวอย่างการใช้งาน ฟังก์ชั่น utf8_to_tis620
ไฟล์ test5.php ที่ถูกเรียก
นอกจากนี้ เรื่องของภาษาเนี่ยยังอาจมีปัญหาอันเกิดจากความแตกต่างของ Server หรือ ความแตกต่างของ Browser ได้อีกด้วยซึ่งก็ทำให้เราจำเป็นต้องทดสอบกับ Server หลายๆแห่ง หรือ Browser หลายๆตัวด้วย
ขั้นตอนที่ 1 กำหนด header เพื่อกำหนดภาษา เป็นการกำหนด Header การเข้ารหัสเอกสารหน้าที่ถูก AJAX เรียกไป (PHP) ให้เป็นภาษาตามที่ต้องการครับ โดยให้เอาคำสั่งนี้ไว้ที่บรรทัดแรกสุดของไฟล์ PHP ถัดจาก <?php เลย
<?php
header("content-type: application/x-javascript; charset=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);