Even if one passes an empty string for the contentType option,
the header is still set.

The interface of the Ajax.Request object has other problems:

Too many implicit defaults (accept, content type, charset
etc).

Does not model the interface of HTTP.

'requestHeaders' are provided as an option, 'encoding' as an
option, 'contentType' as an option, when 'encoding' should be
specified as 'charset' as part of the 'Content-Type' header which
should be a subset of 'requestHeaders'.

If the request headers are provided as 'requestHeaders' then
the request body needs to be provided as 'requestBody' not as
'postBody'. REST concepts such as method, uri, headers, parameters,
representation should not be fused (e.g. 'XMLHttpRequest' which
fuses the content type and the protocol, or 'postBody' which fuses
the method and the representation).

'requestHeaders' smells.

For method overriding, the 'X-Http-Method-Override' header
would be better than the '_method' parameter.

It's not memorable. One has to keep looking up the Ajax options
in the documentation (and where things get implicit, in the
implementation).

Here's a better (and more memorable) interface:

Http.get/set/unset(uri, options) where 'options' has the
following properties: 'headers', 'parameters', 'representation',
onSuccess, 'onTimeout', 'onFailure', and where the response object
passed to the callbacks has the following properties: 'status',
'headers', 'representation'.

Http.delete can't be used as 'delete' is a reserved word.
Http.set does a POST with the 'X-Http-Method-Override' header set
to 'PUT' so as to be idempotent where the server supports PUT.
Http.unset does a POST with the 'X-Http-Method-Override' header set
to 'DELETE'.