diff --git a/src/ajax.js b/src/ajax.js index 0a106ced6..d71ab31cb 100644 --- a/src/ajax.js +++ b/src/ajax.js @@ -179,7 +179,7 @@ if (options.processData && options.data && $.type(options.data) != "string") options.data = $.param(options.data, options.traditional) if (options.data && (!options.type || options.type.toUpperCase() == 'GET')) - options.url = appendQuery(options.url, options.data), options.data = null + options.url = appendQuery(options.url, options.data), options.data = undefined } $.ajax = function(options){ @@ -205,21 +205,26 @@ } var mime = settings.accepts[dataType], - baseHeaders = { }, + headers = { }, + setHeader = function(name, value) { headers[name.toLowerCase()] = [name, value] }, protocol = /^([\w-]+:)\/\//.test(settings.url) ? RegExp.$1 : window.location.protocol, - xhr = settings.xhr(), abortTimeout + xhr = settings.xhr(), + nativeSetHeader = xhr.setRequestHeader, + abortTimeout if (deferred) deferred.promise(xhr) - if (!settings.crossDomain) baseHeaders['X-Requested-With'] = 'XMLHttpRequest' - baseHeaders['Accept'] = mime || '*/*' + if (!settings.crossDomain) setHeader('X-Requested-With', 'XMLHttpRequest') + setHeader('Accept', mime || '*/*') if (mime = settings.mimeType || mime) { if (mime.indexOf(',') > -1) mime = mime.split(',', 2)[0] xhr.overrideMimeType && xhr.overrideMimeType(mime) } if (settings.contentType || (settings.contentType !== false && settings.data && settings.type.toUpperCase() != 'GET')) - baseHeaders['Content-Type'] = (settings.contentType || 'application/x-www-form-urlencoded') - settings.headers = $.extend(baseHeaders, settings.headers || {}) + setHeader('Content-Type', settings.contentType || 'application/x-www-form-urlencoded') + + if (settings.headers) for (name in settings.headers) setHeader(name, settings.headers[name]) + xhr.setRequestHeader = setHeader xhr.onreadystatechange = function(){ if (xhr.readyState == 4) { @@ -256,7 +261,7 @@ var async = 'async' in settings ? settings.async : true xhr.open(settings.type, settings.url, async, settings.username, settings.password) - for (name in settings.headers) xhr.setRequestHeader(name, settings.headers[name]) + for (name in headers) nativeSetHeader.apply(xhr, headers[name]) if (settings.timeout > 0) abortTimeout = setTimeout(function(){ xhr.onreadystatechange = empty diff --git a/test/ajax.html b/test/ajax.html index 6dbd0d127..7fc2d5606 100644 --- a/test/ajax.html +++ b/test/ajax.html @@ -218,6 +218,20 @@

Zepto Ajax unit tests

$.get('echo', { sample: 'plain' }, 'text') }, + testAjaxBeforeSendSetRequestHeader: function(t){ + t.pause() + $.ajax({ + url: 'echo', + beforeSend: function(xhr, settings){ + xhr.setRequestHeader('Accept', 'text/plain') + t.assertUndefined(settings.headers) + }, + success: t.reg.resumeHandler('success', function(response){ + t.assertLine("accept: text/plain", response) + }) + }) + }, + testAjaxPost: function(t){ t.pause() var xhr = $.post('echo', t.reg.resumeHandler('success', function(response){ @@ -739,6 +753,7 @@

Zepto Ajax unit tests

this.async = async }, setRequestHeader: function(name, value) { + if (!this.method) throw "setRequestHeader() called before open()" this.headers.push({ name: name, value: value }) }, getResponseHeader: function(name) { @@ -1088,10 +1103,10 @@

Zepto Ajax unit tests

} }) t.assertEqual('/?a=b', url) - t.assertNull(data) + t.assertUndefined(data) }, - testBeforeSendCanChangeAndAddHeaders: function(t) { + testBeforeSendCannotChangeOrAddHeadersViaObject: function(t) { var xhr = $.ajax({ headers: { a:'b', c:'d' }, beforeSend: function(x, s) { @@ -1099,6 +1114,19 @@

Zepto Ajax unit tests

s.headers['e'] = 'f' } }) + t.assert(xhr.headers.some(matchHeader('a', 'b'))) + t.assert(xhr.headers.some(matchHeader('c', 'd'))) + t.refute(xhr.headers.some(matchHeader('e', 'f'))) + }, + + testBeforeSendCanChangeAndAddHeadersViaXhr: function(t) { + var xhr = $.ajax({ + headers: { a:'b', c:'d' }, + beforeSend: function(x, s) { + x.setRequestHeader('a', 'B') + x.setRequestHeader('e', 'f') + } + }) t.assert(xhr.headers.some(matchHeader('a', 'B'))) t.assert(xhr.headers.some(matchHeader('c', 'd'))) t.assert(xhr.headers.some(matchHeader('e', 'f')))