XMLHttpRequest

Last updated March 3, 2015

Overview

XMLHttpRequest (XHR) is an API in web browsers which provides a mechanism for making HTTP Requests without having to load a new page. For example a live chat box on an e-commerce website. Or streaming stock quotes on a financial website. A common acronym for this loading of data is Ajax (although this is somewhat dated as JSON has become become extremely popular).

XHR is a component of the Browser Object Model (BOM). The BOM is not standardized, but modern browsers are similar. XHR is a web browser API that we access using JavaScript through the XHR object. Some other web browser APIs include Document, History, Location, Navigator, Screen, localStorage, and Audio. Web developers will be most familiar with Document, commonly known as the Document Object Model (DOM).

Today’s major browsers are written in C/C++. The XHR requests are handled through linked compiled files.

The source code for Chromium, the open source project behind Chrome, can be searched online here. It appears XHRs are handled in XMLHttpRequest.cpp, which is a c++ file from WebKit. WebKit is an open source web browser engine use by many browsers. Firefox also has a XMLHttpRequest.cpp file.

Let’s inspect XHR in Safari using the Web Inspector:

xmlhttprequest-object

Objects in JavaScript inherit properties and methods from their prototype object; therefore, when we instantiate a new XMLHttpRequest object it includes everything from window.XMLHttpRequest.prototype.

In the screenshot above we some properties: DONE, HEADERS_RECEIVED, LOADING, OPENED, and USENT. These are readonly properties. The readyState property is assigned one of these properties’ values.

State Value Meaning
UNSENT 0 The object has been constructed.
OPENED 1 The open() method has been successfully invoked. During this state request headers can be set using setRequestHeader() and the request can be made using the send() method.
HEADERS_RECEIVED 2 All redirects (if any) have been followed and all HTTP headers of the final response have been received. Several response members of the object are now available.
LOADING 3 The response entity body is being received.
DONE 4 The data transfer has been completed or something went wrong during the transfer (e.g. infinite redirects).

We also see methods: abort, addEventListener, constructor, dispatchEvent, getAllResponseHeaders, and so on.

Method Meaning
abort Cancels any network activity.
addEventListener Registers a function to call when an event occurs.
constructor Returns a new XMLHttpRequest object.
dispatchEvent Dispatches an event .
getAllResponseHeaders Returns all headers from the response, with the exception of those whose field name is Set-Cookie or Set-Cookie2.
getResponseHeader Returns the header field value from the response of which the field name matches header, unless the field name is Set-Cookie or Set-Cookie2.
open Sets the request method, request URL, and optionally the synchronous flag, username, and password.
overrideMimeType Sets the Content-Type header for the response to mime.
removeEventListener Deregisters a function to call when an event occurs.
send Initiates the request. The optional argument provides the request entity body. The argument is ignored if request method is GET or HEAD.
setRequestHeader Appends a header to the list of author (custom) request headers. If header is already in the list of author request headers, the values are combined.

Example

JavaScript

The JavaScript code below uses XHR to make a request.

var xhr = new XMLHttpRequest();
xhr.addEventListener('load', function(){
	alert('done')
}, false);
xhr.open('GET','http://en.wikipedia.org/wiki/Three-cent_nickel');
xhr.send();

Request

Headers in the HTTP request are observed using Fiddler.

GET http://en.wikipedia.org/wiki/Three-cent_nickel HTTP/1.1
Host: en.wikipedia.org
Connection: keep-alive
User-Agent: Mozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/40.0.2214.115 Safari/537.36
Accept: */*
Referer: http://en.wikipedia.org/wiki/Main_Page
Accept-Encoding: gzip, deflate, sdch
Accept-Language: en-US,en;q=0.8
Cookie: GeoIP=CA:Calgary:51.0426:-114.0791:v4; ...

Response

Headers in the HTTP response are observed using Fiddler.

HTTP/1.1 200 OK
Server: Apache
X-Content-Type-Options: nosniff
X-Analytics: page_id=37856032;ns=0
Content-language: en
Content-Encoding: gzip
X-UA-Compatible: IE=Edge
Vary: Accept-Encoding,Cookie
X-Powered-By: HHVM/3.3.1
Last-Modified: Tue, 03 Mar 2015 18:18:16 GMT
Content-Type: text/html; charset=UTF-8
X-Varnish: 597791747, 3921973502 3921956420, 3061909714 3061568018
Via: 1.1 varnish, 1.1 varnish, 1.1 varnish
Content-Length: 28862
Accept-Ranges: bytes
Date: Tue, 03 Mar 2015 18:28:25 GMT
Age: 575
Connection: keep-alive
X-Cache: cp1053 miss (0), cp4008 hit (1), cp4017 frontend hit (5)
Cache-Control: private, s-maxage=0, max-age=0, must-revalidate
*** content truncated for readability ***

Requests

Below is the JavaScript code for a basic XHR request.

var xhr = new XMLHttpRequest();
	xhr.addEventListener('load', function(){
		alert('done')
	}, false);
xhr.open('GET','http://en.wikipedia.org/wiki/Three-cent_nickel');
xhr.send();

Basic Usage

Create a XHR object:

var xhr = new XMLHttpRequest();

Now initialize the request using the open method. The open method requires two fields, an HTTP method (such as GET, POST, PUT, or DELETE) and a URL.

xhr.open("GET", "http://www.apple.com/");

There are three more optional arguments. A boolean flag for asynchronous, a username, and a password. For example an asynchronous initialization:

xhr.open("DELETE", "http://www.apple.com/", TRUE, "Matthew123", "m0nkys33");

Now we can more information about the request. This is done by setting values for request fields. For example we can set a request field called Cache-Control:

xhr.setRequestHeader('Cache-Control', 'no-cache');

Request Methods

There are 8 common methods specified by IETF for HTTP/1.1. Of these methods, GET and HEAD are considered “safe”. Safe methods only retrieve data, they don’t modify it. The descriptions below come from RFC 7231.

HTTP Method Description
OPTIONS Describe the communication options for the target resource.
GET Transfer a current representation of the target resource.
HEAD Same as GET, but only transfer the status line and header section.
POST Perform resource-specific processing on the request payload.
PUT Replace all current representations of the target resource with the request payload.
DELETE Remove all current representations of the target resource.
TRACE Perform a message loop-back test along the path to the target resource.
CONNECT Establish a tunnel to the server identified by the target resource.

It can be helpful to think of the Request headers as they relate to CRUD. IBM uses the table below to describe the HTTP methods in their Business Process Manager product.

HTTP Method Description
POST Creates a new resource.
GET Retrieves a resource.
PUT Updates an existing resource.
DELETE Deletes a resource.

(via ex0b1t, Stack Overflow)

Standard Request Headers

Standard request fields are set by the Internet Engineering Tast Force (IETF). Below are the standard request headers (ie, client-side javascript requesting data from a server) and the standard response headers (ie, server responding a request). The lists comes from this Wikipedia page.

Header Description Example
Accept Content-Types that are acceptable for the response. Accept: text/plain
Accept-Charset Character sets that are acceptable Accept-Charset: utf-8
Accept-Encoding List of acceptable encodings. Accept-Encoding: gzip, deflate
Accept-Language List of acceptable human languages for response. Accept-Language: en-US
Authorization Authentication credentials for HTTP authentication Authorization: Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ==
Cache-Control Used to specify directives that must be obeyed by all caching mechanisms along the request-response chain Cache-Control: no-cache
Connection Control options for the current connection and list of hop-by-hop request fields Connection: keep-alive
Cookie An HTTP cookie previously sent by the server with Set-Cookie (below) Cookie: $Version=1; Skin=new;
Content-Length The length of the request body in octets (8-bit bytes) Content-Length: 348
Content-MD5 A Base64-encoded binary MD5 sum of the content of the request body Content-MD5: Q2hlY2sgSW50ZWdyaXR5IQ==
Content-Type The MIME type of the body of the request (used with POST and PUT requests) Content-Type: application/x-www-form-urlencoded
Date The date and time that the message was sent Date: Tue, 15 Nov 1994 08:12:31 GMT
Expect Indicates that particular server behaviors are required by the client Expect: 100-continue
From The email address of the user making the request From: user@example.com
Host The domain name of the server (for virtual hosting), and the TCP port number on which the server is listening. The port number may be omitted if the port is the standard port for the service requested. Host: en.wikipedia.org:80
If-Match Only perform the action if the client supplied entity matches the same entity on the server. This is mainly for methods like PUT to only update a resource if it has not been modified since the user last updated it. If-Match: “737060cd8c284d8af7ad3082f209582d”
If-Modified-Since Allows a 304 Not Modified to be returned if content is unchanged If-Modified-Since: Sat, 29 Oct 1994 19:43:31 GMT
If-None-Match Allows a 304 Not Modified to be returned if content is unchanged If-None-Match: “737060cd8c284d8af7ad3082f209582d”
If-Range If the entity is unchanged, send me the part(s) that I am missing; otherwise, send me the entire new entity If-Range: “737060cd8c284d8af7ad3082f209582d”
If-Unmodified-Since Only send the response if the entity has not been modified since a specific time If-Unmodified-Since: Sat, 29 Oct 1994 19:43:31 GMT
Max-Forwards Limit the number of times the message can be forwarded through proxies or gateways. Max-Forwards: 10
Origin Initiates a request for cross-origin resource sharing (asks server for an ‘Access-Control-Allow-Origin’ response field) . Origin: http://www.example-social-network.com
Pragma Implementation-specific fields that may have various effects anywhere along the request-response chain. Pragma: no-cache
Proxy-Authorization Authorization credentials for connecting to a proxy. Proxy-Authorization: Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ==
Range Request only part of an entity. Bytes are numbered from 0. Range: bytes=500-999
Referer This is the address of the previous web page from which a link to the currently requested page was followed. Referer: http://en.wikipedia.org/wiki/Main_Page
TE The transfer encodings the user agent is willing to accept: the same values as for the response header field Transfer-Encoding can be used, plus the “trailers” value (related to the “chunked” transfer method) to notify the server it expects to receive additional fields in the trailer after the last, zero-sized, chunk. TE: trailers, deflate
User-Agent The user agent string of the user agent User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:12.0) Gecko/20100101 Firefox/21.0
Upgrade Ask the server to upgrade to another protocol. Upgrade: HTTP/2.0, SHTTP/1.3, IRC/6.9, RTA/x11
Via Informs the server of proxies through which the request was sent. Via: 1.0 fred, 1.1 example.com (Apache/1.1)
Warning A general warning about possible problems with the entity body. arning: 199 Miscellaneous warning

Additional common non-standard request fields are listed on Wikipedia.


Responses

Below is the captured response from a server.

HTTP/1.1 200 OK
Cache-Control: no-cache
Pragma: no-cache
Content-Length: 0
Expires: -1
Server: Microsoft-IIS/8.0
Access-Control-Allow-Origin: http://www.matt.ca
Access-Control-Allow-Headers: cache-control,content-type
X-AspNet-Version: 4.0.30319
X-Powered-By: ASP.NET
Set-Cookie: ARRAffinity=89b70e2fb8b56922abb4be884722be266925fa22c42cca78f9b0b7dfa040
Date: Tue, 03 Mar 2015 23:13:54 GMT

Standard Response Headers

Standard response fields are set by the Internet Engineering Tast Force (IETF). Below are the standard request headers (ie, client-side javascript requesting data from a server) and the standard response headers (ie, server responding a request). The lists comes from this Wikipedia page.

Header Description Example
Access-Control-Allow-Origin Specifying which web sites can participate in cross-origin resource sharing Access-Control-Allow-Origin: *
Accept-Patch Specifies which patch document formats this server supports Accept-Patch: text/example;charset=utf-8
Accept-Ranges What partial content range types this server supports Accept-Ranges: bytes
Age The age the object has been in a proxy cache in seconds Age: 12
Allow Valid actions for a specified resource. To be used for a 405 Method not allowed Allow: GET, HEAD
Cache-Control Tells all caching mechanisms from server to client whether they may cache this object. It is measured in seconds Cache-Control: max-age=3600
Connection Control options for the current connection and list of hop-by-hop response fields Connection: close
Content-Encoding The type of encoding used on the data. See HTTP compression. Content-Encoding: gzip
Content-Language The language the content is in Content-Language: da
Content-Length The length of the response body in octets (8-bit bytes) Content-Length: 348
Content-Location An alternate location for the returned data Content-Location: /index.htm
Content-MD5 A Base64-encoded binary MD5 sum of the content of the response Content-MD5: Q2hlY2sgSW50ZWdyaXR5IQ==
Content-Disposition An opportunity to raise a “File Download” dialogue box for a known MIME type with binary format or suggest a filename for dynamic content. Quotes are necessary with special characters. Content-Disposition: attachment; filename=”fname.ext”
Content-Range Where in a full body message this partial message belongs Content-Range: bytes 21010-47021/47022
Content-Type The MIME type of this content Content-Type: text/html; charset=utf-8
Date The date and time that the message was sent Date: Tue, 15 Nov 1994 08:12:31 GMT
ETag An identifier for a specific version of a resource, often a message digest ETag: “737060cd8c284d8af7ad3082f209582d”
Expires Gives the date/time after which the response is considered stale (in “HTTP-date” format as defined by RFC 7231) Expires: Thu, 01 Dec 1994 16:00:00 GMT
Last-Modified The last modified date for the requested object (in “HTTP-date” format as defined by RFC 7231) Last-Modified: Tue, 15 Nov 1994 12:45:26 GMT
Link Used to express a typed relationship with another resource, where the relation type is defined by RFC 5988 Link: ; rel=”alternate”
Location Used in redirection, or when a new resource has been created. Location: http://www.w3.org/pub/WWW/People.html
Pragma Implementation-specific fields that may have various effects anywhere along the request-response chain. Pragma: no-cache
Proxy-Authenticate Request authentication to access the proxy. Proxy-Authenticate: Basic
Refresh Used in redirection, or when a new resource has been created. This refresh redirects after 5 seconds. Refresh: 5; url=http://www.w3.org/pub/WWW/People.html
Retry-After If an entity is temporarily unavailable, this instructs the client to try again later. Retry-After: 120
Server A name for the server Server: Apache/2.4.1 (Unix)
Set-Cookie An HTTP cookie Set-Cookie: UserID=JohnDoe; Max-Age=3600; Version=1
Status CGI header field specifying the status of the HTTP response. Normal HTTP responses use a separate “Status-Line” instead, defined by RFC 7230. Status: 200 OK
Strict-Transport-Security A HSTS Policy informing the HTTP client how long to cache the HTTPS only policy and whether this applies to subdomains. Strict-Transport-Security: max-age=16070400; includeSubDomains
Trailer The Trailer general field value indicates that the given set of header fields is present in the trailer of a message encoded with chunked transfer coding. Trailer: Max-Forwards
Transfer-Encoding The form of encoding used to safely transfer the entity to the user. Currently defined methods are: chunked, compress, deflate, gzip, identity. Transfer-Encoding: chunked
Upgrade Ask the client to upgrade to another protocol. Upgrade: HTTP/2.0, SHTTP/1.3, IRC/6.9, RTA/x11
Vary Tells downstream proxies how to match future request headers to decide whether the cached response can be used rather than requesting a fresh one from the origin server. Vary: *
Via Informs the client of proxies through which the response was sent. Via: 1.0 fred, 1.1 example.com (Apache/1.1)
Warning A general warning about possible problems with the entity body. Warning: 199 Miscellaneous warning
WWW-Authenticate Indicates the authentication scheme that should be used to access the requested entity. WWW-Authenticate: Basic
X-Frame-Options[34] Clickjacking protection: deny – no rendering within a frame, sameorigin – no rendering if origin mismatch, allow-from – allow from specified location, allowall – non-standard, allow from any location X-Frame-Options: deny

Additional common non-standard response fields are listed on Wikipedia.

HTTP Response Status Codes

The first line in the response from the server looks like:
HTTP/1.1 200 ok

What this says is that the server is responding with the HTTP 1.1 protocol, status code 200, and status message “ok”.

The official registry of HTTP status codes is maintained by the Internet Assigned Numbers Authority (IANA).

HTTP Status Code Meaning
100 Continue
101 Switching Protocols
102 Processing
103-199 Unassigned
200 OK
201 Created
202 Accepted
203 Non-Authoritative Information
204 No Content
205 Reset Content
206 Partial Content
207 Multi-Status
208 Already Reported
209-225 Unassigned
226 IM Used
227-299 Unassigned
300 Multiple Choices
301 Moved Permanently
302 Found
303 See Other
304 Not Modified
305 Use Proxy
306 (Unused)
307 Temporary Redirect
308 Permanent Redirect
309-399 Unassigned
400 Bad Request
401 Unauthorized
402 Payment Required
403 Forbidden
404 Not Found
405 Method Not Allowed
406 Not Acceptable
407 Proxy Authentication Required
408 Request Timeout
409 Conflict
410 Gone
411 Length Required
412 Precondition Failed
413 Payload Too Large
414 URI Too Long
415 Unsupported Media Type
416 Range Not Satisfiable
417 Expectation Failed
418-420 Unassigned
421 Misdirected Request
422 Unprocessable Entity
423 Locked
424 Failed Dependency
425 Unassigned
426 Upgrade Required
427 Unassigned
428 Precondition Required
429 Too Many Requests
430 Unassigned
431 Request Header Fields Too Large
432-499 Unassigned
500 Internal Server Error
501 Not Implemented
502 Bad Gateway
503 Service Unavailable
504 Gateway Timeout
505 HTTP Version Not Supported
506 Variant Also Negotiates
507 Insufficient Storage
508 Loop Detected
509 Unassigned
510 Not Extended
511 Network Authentication Required
512-599 Unassigned

Cross Domain Requests

One issue with XHR is that web browsers block cross domain requests. This blocking is a result of the same-origin policy, meaning that JavaScript on one webpage cannot access the content from another domain. Read an example of an exploit here.

CORS

Cross-origin resource sharing (CORS) is a feature of modern browsers. When requesting a resource on a different domain, the browser will do a preflight check. This is done by sending a a request to the target server which contains a header called Origin. The server checks to see if the origin is something it allows, if it does allow it, the server responds with a header called Access-Control-Allow-Origin containing the allowed domain. Once the preflight check is complete, the actual request will proceed.

JavaScript

var xhr = new XMLHttpRequest();
xhr.open('POST','http://example-event-logger.azurewebsites.net/api/logevent');
xhr.setRequestHeader('Cache-Control', 'no-cache');
xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded'); 
xhr.addEventListener('load', function(){
	success();
}, false);
xhr.send('content');

Request

OPTIONS http://example-event-logger.azurewebsites.net/api/logevent HTTP/1.1
Accept: */*
Origin: http://dev-site-1
Access-Control-Request-Method: POST
Access-Control-Request-Headers: cache-control, content-type
Accept-Encoding: gzip, deflate
User-Agent: Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.3; WOW64; Trident/7.0; .NET4.0E; .NET4.0C; .NET CLR 3.5.30729; .NET CLR 2.0.50727; .NET CLR 3.0.30729; InfoPath.3)
Host: example-event-logger.azurewebsites.net
Content-Length: 0
DNT: 1
Connection: Keep-Alive
Pragma: no-cache

Response

HTTP/1.1 200 OK
Cache-Control: no-cache
Pragma: no-cache
Content-Length: 0
Expires: -1
Server: Microsoft-IIS/8.0
Access-Control-Allow-Origin: http://dev-site-1
Access-Control-Allow-Headers: cache-control,content-type
X-AspNet-Version: 4.0.30319
X-Powered-By: ASP.NET
Set-Cookie: ARRAffinity=89b70e2fb8b56922abb4be884722be266925fa22c42cca78f9b0b7dfa0404288;Path=/;Domain=example-event-logger.azurewebsites.net
Date: Tue, 03 Mar 2015 23:13:54 GMT

JSONP

Another option for getting around the same-origin policy is to use a feature of the script tag. Browsers permit us to put in these script tags from other domains. For example we can include Google’s jQuery CDN on any webpage:

<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script>

With JSONP this feature is taken a step further. A server is programmed to respond to a HTTP request with a string, the string looks like a JavaScript function with a JSON object as it’s argument. This response is executed as JavaScript on the client. For example calling the GitHub status api from WikiPedia:

Predefine a JavaScript function:

<script> function apiStatus(data) { console.log(data.status); } </script>

Then insert a script block into the page. The src attribute is the remote content to load:

<script src="https://status.github.com/api/status.json?callback=apiStatus"></script>

The script block loads this code:

apiStatus({"status":"good","last_updated":"2015-03-04T16:51:43Z"})

The code above calls the predefined function, apiStatus, with data from the remote domain.

XDomainRequest

XDomainRequest is an API from Microsoft which provides support for CORS in IE 8 and 9, it was replaced by XMLHttpRequest in IE10.


jQuery Ajax

The purpose of jQuery is to make working with javascript easier and consistent across browsers. The $.ajax method provides XHR functionality without having to create an instance of XHR yourself.

Looking inside the uncompressed jQuery library (http://code.jquery.com/jquery-2.1.3.js) we can see the usage of XHR on line 8514:

jQuery.ajaxSettings.xhr = function() {
	try {
		return new XMLHttpRequest();
	} catch( e ) {}
};

jQuery GET Request

JavaScript

$.ajax({
  url: 'http://en.wikipedia.org/wiki/Three-cent_nickel',
}).done(function() {
  alert('done');
});

Request

GET http://en.wikipedia.org/wiki/Three-cent_nickel HTTP/1.1
Host: en.wikipedia.org
Connection: keep-alive
Accept: */*
X-Requested-With: XMLHttpRequest
User-Agent: Mozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/40.0.2214.115 Safari/537.36
Referer: http://en.wikipedia.org/wiki/Three-cent_nickel
Accept-Encoding: gzip, deflate, sdch
Accept-Language: en-US,en;q=0.8
Cookie: centralnotice-frbanner-seen-fullscreen=1417715788184; ...
If-Modified-Since: Tue, 03 Mar 2015 16:21:15 GMT

Response

HTTP/1.1 200 OK
Server: Apache
X-Content-Type-Options: nosniff
X-Analytics: page_id=37856032;ns=0
Content-language: en
Content-Encoding: gzip
X-UA-Compatible: IE=Edge
Vary: Accept-Encoding,Cookie
X-Powered-By: HHVM/3.3.1
Last-Modified: Tue, 03 Mar 2015 18:18:16 GMT
Content-Type: text/html; charset=UTF-8
X-Varnish: 597791747, 3921987500 3921956420, 2550785707 2550627932
Via: 1.1 varnish, 1.1 varnish, 1.1 varnish
Content-Length: 28862
Accept-Ranges: bytes
Date: Tue, 03 Mar 2015 18:24:17 GMT
Age: 327
Connection: keep-alive
X-Cache: cp1053 miss (0), cp4008 hit (2), cp4009 frontend hit (3)
Cache-Control: private, s-maxage=0, max-age=0, must-revalidate
*** content truncated for readability ***

jQuery IE8/9 Cross Domain Issue

jQuery does not gracefully fallback to using XDomainRequest when XMLHttpRequest isn’t available. This is an issue for web developers needing to support IE 8 and 9, as described in this question on StackOverflow. A support ticket about this issue on jQuery’s official bug tracker indicates developer’s should use a plugin.

MoonScript has a plugin for adding XDomainRequest suppot to jQuery. To use it just include the script:

<script src="http://cdnjs.cloudflare.com/ajax/libs/jquery-ajaxtransport-xdomainrequest/1.0.3/jquery.xdomainrequest.min.js"></script>

HTTPS

The HTTPS protocol can be used secure XHR communication between client and server. Everything gets encrypted except for the host address and port number.

Example

JavaScript

The JavaScript code below uses XHR to make a request.

var xhr = new XMLHttpRequest();
xhr.addEventListener('load', function(){
	alert('done')
}, false);
xhr.open('GET','https://status.github.com/api/status.json');
xhr.send();

Request

Headers in the HTTP request are observed using Fiddler.

CONNECT status.github.com:443 HTTP/1.1
Host: status.github.com
Connection: keep-alive
User-Agent: Mozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2272.89 Safari/537.36

A SSLv3-compatible ClientHello handshake was found. Fiddler extracted the parameters below.

Version: 3.3 (TLS/1.2)
Random: F7 F2 B3 F9 57 76 37 E9 63 90 9E 5B 5A 48 31 CE E7 14 AB 3E 0A 25 FB 5D BB 8D 3A 7C 37 69 E6 B8
"Time": 10/3/2102 4:58:47 AM
SessionID: 17 28 99 46 C3 E1 56 73 82 58 5D 33 37 3B 6B 0A D5 3F 35 DA BB 52 DD C4 8D 2F 24 6E B7 7D 68 E4
Extensions: 
	server_name	status.github.com
	0x0017		empty
	SessionTicket	2B 23 96 6E 9C 04 16 DC 65 CB 52 08 F4 6D 34 22 4C 9A 47 F1 E6 E0 17 DC 05 0E E3 A1 BC DE BA 64 AB 3D A3 EA 4F 99 FD F0 18 5F CC AE EB 77 25 2B 15 68 52 95 84 48 15 54 46 F8 6A 3D 3F 79 9F 60 E3 12 1E 2E 5D 54 D6 32 42 3F 7F 9B 62 5E 89 C3 D5 09 B9 73 BC 25 1A E6 25 A8 F6 71 71 66 9C 53 48 F6 57 D3 86 46 F4 20 F8 E5 8B FA 26 12 62 7E 3A 5C AF 27 2F 7A CC 88 1C B5 6A 43 F9 B1 55 5B 10 2A 99 E5 4D A6 62 F1 20 FA 39 97 7A 86 B2 45 39 74 0E 96 14 78 52 22 05 2F E1 DD 73 4F F4 9B 9B E8 75 2E F1 FA 6E BE FA C3 A1 3F ED 81 35 F4
	signature_algorithms	sha512_rsa, sha512_ecdsa, sha384_rsa, sha384_ecdsa, sha256_rsa, sha256_ecdsa, sha224_rsa, sha224_ecdsa, sha1_rsa, sha1_ecdsa
	status_request	OCSP - Implicit Responder
	NextProtocolNegotiation	empty
	SignedCertTimestamp (RFC6962)	empty
	ALPN		http/1.1, spdy/3.1, h2-14
	channel_id(GoogleDraft)	empty
	ec_point_formats	uncompressed [0x0]
	elliptic_curves	secp256r1 [0x17], secp384r1 [0x18], secp521r1 [0x19]
	padding	00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
Ciphers: 
	[C02B]	TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256
	[C02F]	TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
	[009E]	TLS_DHE_RSA_WITH_AES_128_GCM_SHA256
	[CC14]	TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256
	[CC13]	TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256
	[CC15]	Unrecognized cipher - See http://www.iana.org/assignments/tls-parameters/
	[C00A]	TLS1_CK_ECDHE_ECDSA_WITH_AES_256_CBC_SHA
	[C014]	TLS1_CK_ECDHE_RSA_WITH_AES_256_CBC_SHA
	[0039]	TLS_DHE_RSA_WITH_AES_256_SHA
	[C009]	TLS1_CK_ECDHE_ECDSA_WITH_AES_128_CBC_SHA
	[C013]	TLS1_CK_ECDHE_RSA_WITH_AES_128_CBC_SHA
	[0033]	TLS_DHE_RSA_WITH_AES_128_SHA
	[C007]	TLS_ECDHE_ECDSA_WITH_RC4_128_SHA
	[C011]	TLS_ECDHE_RSA_WITH_RC4_128_SHA
	[009C]	TLS_RSA_WITH_AES_128_GCM_SHA256
	[0035]	TLS_RSA_AES_256_SHA
	[002F]	TLS_RSA_AES_128_SHA
	[0005]	SSL_RSA_WITH_RC4_128_SHA
	[0004]	SSL_RSA_WITH_RC4_128_MD5
	[000A]	SSL_RSA_WITH_3DES_EDE_SHA
	[00FF]	TLS_EMPTY_RENEGOTIATION_INFO_SCSV

Compression: 
	[00]	NO_COMPRESSION

Response

Headers in the HTTP response are observed using Fiddler.

HTTP/1.1 200 Connection Established
FiddlerGateway: Direct
StartTime: 21:08:39.674
Connection: close
EndTime: 21:08:44.815
ClientToServerBytes: 1496
ServerToClientBytes: 592

This is a CONNECT tunnel, through which encrypted HTTPS traffic flows.
To view the encrypted sessions inside this tunnel, enable the Tools > Fiddler Options > HTTPS > Decrypt HTTPS traffic option.

A SSLv3-compatible ServerHello handshake was found. Fiddler extracted the parameters below.

Version: 3.3 (TLS/1.2)
SessionID:	17 28 99 46 C3 E1 56 73 82 58 5D 33 37 3B 6B 0A D5 3F 35 DA BB 52 DD C4 8D 2F 24 6E B7 7D 68 E4
Random:		55 0A 4B C7 14 4A 38 C3 02 D9 66 78 12 AD 48 81 51 92 15 8D 7D 2B BE 13 E1 13 04 E9 68 DE 2B 94
Cipher:		TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 [0xC02F]
CompressionSuite:	NO_COMPRESSION [0x00]
Extensions:
		renegotiation_info	00

Alternatives

WebSockets

WebSockets are a way of communicating between client and server over a single TCP connection. It much faster to send messages back and forth over a WebSocket than using XHR. WebSockets only have to setup one TCP connection whereas XHR has to setup one TCP connection for each request.

WebSocket is a different world than XHR. Whereas XHR is simply a browser API for making HTTP requests, WebSocket is a new protocol. WebSockets are full duplex, meaning communication can be done in either direction at the same time, like a telephone call. XHRs are half-duplex, meaning communication can only be done in one direction at a time, like a walkie-talkie.

However WebSocket communications are still done over port 80 (same as HTTP) and XHR is still used for the initial handshake. Basically the process for setting up a WebSocket is a browser and server shake hands and agree to begin speaking WebSocket.

WebSockets appear to be handled in chrome inside websocket.cc and in FireFox inside WebSocket.cpp.

SignalR

SignalR is an open source library for ASP.NET. “SignalR will use WebSockets under the covers when it’s available, and gracefully fallback to other techniques and technologies when it isn’t, while your application code stays the same.” (signalr.net)

Sockets.IO

Sockets.IO is an open source library for Node.js. It works similarly to SignalR by utilizing WebSockets when available and falling back to polling when not.