ใช้ cURL ยิง HTTP POST และ GET

@pittaya แนะนำผมมาหลายครั้งว่าให้ใช้ cURL แทน wget หรือการเขียนโปรแกรมมายิง HTTP request เอง

วันก่อนได้มีโอกาสลองกับ server ของตัวเองที่ office (เป็น Red Hat Enterprise Linux 5) แล้วก็พบว่ามันง่ายดี ^^

การลง cURL ใน RHEL นี่เหมือนมันจะมี binary ให้ load อยู่แล้ว แต่ลงกดๆ ใน page แล้วงงว่าอันไหนใหม่สุด ก็เลย load source code ไป build ตาม http://curl.haxx.se/docs/install.html เลย (งงตรงที่ readme ที่ได้จาก package ไม่บอกวิธี build แฮะ) ลงเสร็จเราก็จะได้ curl command ไว้ใช้ครับ

สำหรับ GET ก็ง่าย แค่สั่ง

$> curl <URL>

แล้ว response จะถูก display ออกมาเลย ไม่เหมือน wget ที่จะ save ลง file เป็นชื่อ path สุดท้ายเสมอ

$> curl http://localhost:8080/json/quote/FB
{"bid":10,"ask":10,"time":18:48.41}
$>

เราจะใช้ -> redirect ลง file ก็ได้เหมือนกัน สะดวกดี

$> curl http://localhost:8080/json/quote/FB  -> fb.txt
 % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100  6281    0  6281    0     0   803k      0 --:--:-- --:--:-- --:--:--  876k
$> cat fb.txt
{"bid":10,"ask":10,"time":18:48.41}

สำหรับ POST ก็ต้องเพิ่ม parameter สำหรับใส่ data และระบุว่า Content-type แบบไหนเข้าไป ซึ่ง ที่ผมใช้เลือกเป็น application/json

$> curl -X POST -H 'Accept: application/json' -H 'Content-type:<Content-type>' -d '<data>' <URL>
$> curl -X POST -H 'Accept: application/json' -H 'Content-type:application/json' -d '{"request":"GOOG","compare":"AAPL"}' http://localhost:8080/json/ts
{"item":"GOOG",data:["bid":10,"ask":10,"time":18:48.41],"item":"AAPL",data:["bid":1,"ask":1,"time":18:48.41]}
$>

ส่วนตัว cURL เมื่อเทียบกับ wget ผมรู้สึก cURL แม้คำสั่งจะยาวกว่า แต่ก็ยืดหยุ่นกว่า ดูผลง่ายกว่าและ save ลง file เป็นชื่อที่ต้องการได้ครับ

ใช้ wget ยิง post และ get request

เดือนที่แล้วถูกหลอกให้ลง program ที่ปล่อยข้อมูลลงมาเป็น http rest ในเครื่อง server ของลูกค้า ลงเสร็จก็ต้องมีการเทสว่า program มันทำงานได้ไหม ซึ่งวิธีที่่ง่ายที่สุดคือยิง request ทาง ssh ที่ login อยู่นั่นแหละ

เครื่องของลูกค้าที่ลงเป็น RHEL 5 เขาให้ access ผ่าน ssh ได้ (แต่ remote กันไป 2 ชั้น) เครื่องนั้นต่อเนตไม่ได้ด้วยเลยไม่ได้ลง cURL ตามที่ @pittaya แนะนำ เลยใช้ wget ที่ติดมากับเครื่องนี่แหละ ง่ายดี

สำหรับ GET ก็ง่าย แค่สั่ง

$> wget <URL>

แล้ว response จะถูก save ลง path สุดท้ายของ url ที่เราใส่ครับ เช่น

$> wget http://localhost:8080/json/quote/FB

response จะถูก save ลง file ชื่อ FB ซึ่งเราก็ไป vi หรือ cat ดูได้

สำหรับ POST ก็ต้องเพิ่ม –post-data เข้าไป (เอาวิธีมาจาก http://grep.codeconsult.ch/2005/01/21/wget-19-can-do-post-as-well/)

$> wget --post-data '<parameter>' <URL>

ตัวอย่าง

$> wget --post-data '{"request":"GOOG","compare":"AAPL"}' http://localhost:8080/json/ts

response จาก server ก็จะถูก save ลง file ชื่อ ts ครับ

ง่ายดี เห็นมั้ย ^^

JavaScript check null

อาทิตย์ที่ผ่านมาเพื่อนผมในทีมได้รับ support case ว่า JavaScript API ที่ support อยู่ไม่รองรับค่า null ที่ server โผล่มา คือพอ server ส่ง null ลงมาเป็นค่าใน json แบบนี้

{"data":null}

แล้วที่ browser จะเจ๊งเลย แล้วโยน error TypeError: is null ทำนองนี้ขึ้นมา

พอลองตรวจสอบดูพบว่าปกติ server ถ้าข้อมูลมีค่ามันจะส่งลงมาเป็น object ซ้อนอีกทีแบบนี้

{"data":{"a":1,"h":"FFFFF"}}

พอลองดู code JavaScript ที่ใช้ดึงค่า จะ check ว่าเป็น object หรือไม่ ถ้าใช่ก็ดึงค่า propery a หรือ h ออกมาใช้งาน ทำนองนี้

function process_data(data){
	if(typeof data ==="object"){
		console.log('a='+a.a+',h='+a.h);
	}
}

code มันก็ดูเหมือนจะได้อ่ะนะ แต่พอ check typeof refference ดูก็พบว่า typeof จะ return ผลการตรวจค่า null ออกมาเป็น “object” เสมอ พอ server ส่ง null มาเลยไม่รอด ไป access key ที่ไม่มีจริงก็เลยเจ๊งกันไป ซึ่งผมเองก็เพิ่งรู้เหมือนกันว่า typeof มันใช้ตรวจค่า null ไม่ได้ เพราะปกติใช้แต่ if check เอา – -”

เลยลองดูง่ายๆ บน JavaScript Console (เซ็งตรงมันต้องเขียน line เดียวนี่แหละ)

var nn=null;
if(typeof nn==='object'){
	console.log('object');
}else{
	console.log('else');
} 
//print 'object'
if(nn){
	console.log('value');
}else{
	console.log('else');
} 
//print 'else'

ก็เลยได้รู้ว่า typeof มันใช้ check null ไม่ได้ (แต่ check undefined ได้นะ)