Oscar Tong
Everything that has a beginning has an end.
Ajax & WebSocket
- Oscar Tong / @oscartong

How it works ?
//create a XHR instance
var request = new XMLHttpRequest();
//listen for readyStateChange event
request.onreadystatechange = function(e){
if(request.readyState === 4 && request.status === 200){
console.log(request.responseText);
}
};
//send request
request.open('GET', 'http://www.example.com/foo', true);
request.send();
//initiate a XMLHttpRequest and handle timeout situation
var xhr = new XMLHttpRequest();
xhr.open('GET', 'foo');
xhr.timeout = 3000;
xhr.onload = onLoad;
xhr.ontimeout = onTimeout;
xhr.send();
//timeout event handler
function onTimeout(event){
var xhr = event.target;
//set a higher timeout value and resend the request
xhr.timeout = 6000;
xhr.open('GET', 'foo');
xhr.send();
}
//create a form and append data
var formdata = new FormData();
formdata.append('username', 'Oscar Tong');
formdata.append('id', 1234); //number 1234 is converted to string '1234'
formdata.append('file', someFileInput.files[0]);
//create a request and post formdata
var xhr = new XMLHttpRequest();
xhr.open('POST', 'http://www.foo.com/bar.php');
xhr.send(formdata);
var xhr = new XMLHttpRequest();
xhr.open('GET', 'foo');
//set responseType as arraybuffer to send/receive binary data
xhr.responseType = 'arraybuffer';
xhr.onload = function(){
var arraybuffer = xhr.response; //not responseText
....
};
xhr.send();
//handle progress and other level2 events
var xhr = new XMLHttpRequest();
xhr.addEventListener('progress', onProgress);
xhr.addEventListener('load', onComplete);
xhr.addEventListener('error', onError);
xhr.addEventListener('abort', onCanceled);
function onProgress(event){
if(event.lengthComputable){
console.log('percent complete:', event.loaded / event.total);
}
else{
//total size is unknown yet
}
}
function onComplete(event){ ... }
function onError(event){ ... }
function onCanceled(event){ ... }

//CORS means Cross Origin Resource Sharing
function createCORSRequest(method, url){
var xhr = new XMLHttpRequest();
if('withCredentials' in xhr){
//check if the XMLHttpRequest object has a 'withCredentials' property
//which only exists on XMLHttpRequest Level 2 object
xhr.open(method, url, true);
}
else if(typeof XDomainRequest != 'undefined'){
//otherwise check if XDomainRequest exists
//XDomainRequest only exists in IE, it is IE's way of making CORS request
xhr = new XDomainRequest();
xhr.open(method, url);
}
else{
//sorry, your browser does not supports CORS
xhr = null;
}
}
//creating and sending a CORS request
var xhr = createCORSRequest('GET', 'http://api.twitter.com/foo');
xhr.send();
HTTP Request:
GET /foo HTTP/1.1 Origin: http://www.example.com Host: http://api.twitter.com Accept-Language: en-US User-Agent: Mozilla/5.0 ... HTTP Response: ... Access-Control-Allow-Origin: http://www.example.com Access-Control-Allow-Credentials: true Acceee-Control-Expose-Headers: Foo,Bar Content-Type: text/html; charset=utf-8 ...
GET /chat HTTP/1.1 Host: server.example.com Upgrade: websocket Connection: Upgrade Origin: http://example.com Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ== Sec-WebSocket-Protocol: chat, superchat Sec-WebSocket-Version: 13
Server > Client
HTTP/1.1 101 Switching Protocols Upgrade: websocket Connection: Upgrade Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo= Sec-WebSocket-Protocol: chat
GUID = '258EAFA5-E914-47DA-95CA-C5AB0DC85B11' Sec-WebSocket-Accept = base64( sha1( Sec-WebSocketKey + GUID ) )
0 1 2 3 0 1 2 3 4 5 6 7 0 1 2 3 4 5 6 7 0 1 2 3 4 5 6 7 0 1 2 3 4 5 6 7 +-+-+-+-+-------+-+-------------+------------------------------+ |F|R|R|R| Opcode|M| Payload len | Extended payload length | |I|S|S|S| (4) |A| (7) | (16 or 64) | |N|V|V|V| |S| | (if payload len == 126/127) | | |1|2|3| |K| | | +-+-+-+-+-------+-+-------------+------------------------------+ | Extended payload length continued, if payload len == 127 | +-------------------------------+------------------------------+ | |Masking-key, if MASK set to 1 | +-------------------------------+------------------------------+ | Masking-key continued | Payload Data | +-------------------------------+------------------------------+ : Payload Data continued ... : +--------------------------------------------------------------+ | Payload Data continued ... | +--------------------------------------------------------------+
0 1 2 3 0 1 2 3 4 5 6 7 0 1 2 3 4 5 6 7 0 1 2 3 4 5 6 7 0 1 2 3 4 5 6 7 +-+-+-+-+-------+-+-------------+------------------------------+ |F|R|R|R| Opcode|M| Payload len | Extended payload length | |I|S|S|S| (4) |A| (7) | (16 or 64) | |N|V|V|V| |S| | (if payload len == 126/127) | | |1|2|3| |K| | | +-+-+-+-+-------+-+-------------+------------------------------+ ... Text frame: +-+-+-+-+-------+-+-------------+-----------+ |1|0|0|0| 0x1 |0| 11 |Hello World| +-+-+-+-+-------+-+-------------+-----------+
0 1 2 3 0 1 2 3 4 5 6 7 0 1 2 3 4 5 6 7 0 1 2 3 4 5 6 7 0 1 2 3 4 5 6 7 +-+-+-+-+-------+-+-------------+------------------------------+ |F|R|R|R| Opcode|M| Payload len | Extended payload length | |I|S|S|S| (4) |A| (7) | (16 or 64) | |N|V|V|V| |S| | (if payload len == 126/127) | | |1|2|3| |K| | | +-+-+-+-+-------+-+-------------+------------------------------+ ... Close frame: +-+-+-+-+-------+-+-------------+ |1|0|0|0| 0x8 |0| 0 | +-+-+-+-+-------+-+-------------+
//creating a WebSocket instance and try connect to the server
var socket = new WebSocket('ws://www.example.com/socketserver');
//open event is fired when WebSocket is connected
socket.onopen = function(event){
socket.send('Hello Server. How are you?');
};
//message event is fire when message is received from server
socket.onmessage = function(event){
console.log('Server said:', event.data);
};
...
//close the WebSocket connection
socket.close();Demo(Telnet Client)

By Oscar Tong