From 5b771aafcc5c1bc6ccccbce789f953a2485acbbb Mon Sep 17 00:00:00 2001 From: Piotr Sarnacki Date: Tue, 7 May 2013 18:56:02 +0200 Subject: [PATCH] Use XMLHttpRequest directly jQuery uses getAllResponseHeaders function for getting response headers, even for getResponseHeader. As far as I know, there is no easy way to get original xhr object and call getResponseHeader on such object. Because of that getResponseHeader is broken on firefox with CORS. I rewrote Travis.ajax to use XMLHttpRequest directly in order to fix this, the compatibility with jQuery.ajax is mostly handled. --- assets/scripts/lib/travis/ajax.coffee | 53 ++++++++++++++++++++++++--- 1 file changed, 48 insertions(+), 5 deletions(-) diff --git a/assets/scripts/lib/travis/ajax.coffee b/assets/scripts/lib/travis/ajax.coffee index ec025cae..878541af 100644 --- a/assets/scripts/lib/travis/ajax.coffee +++ b/assets/scripts/lib/travis/ajax.coffee @@ -5,7 +5,7 @@ Travis.ajax = Em.Object.create DEFAULT_OPTIONS: accepts: - json: 'application/vnd.travis-ci.2+json' + json: 'application/json; version=2' get: (url, callback) -> @ajax(url, 'get', success: callback) @@ -14,6 +14,7 @@ Travis.ajax = Em.Object.create @ajax(url, 'post', data: data, success: callback) needsAuth: (method, url) -> + return true if Travis.ajax.pro return true if method != 'GET' result = @publicEndpoints.find (pattern) -> @@ -23,6 +24,7 @@ Travis.ajax = Em.Object.create ajax: (url, method, options) -> method = method.toUpperCase() + endpoint = Travis.config.api_endpoint || '' options = options || {} @@ -31,7 +33,7 @@ Travis.ajax = Em.Object.create options.headers ||= {} options.headers['Authorization'] ||= "token #{token}" - options.url = "#{endpoint}#{url}" + url = "#{endpoint}#{url}" options.type = method options.dataType = options.dataType || 'json' options.context = this @@ -43,15 +45,56 @@ Travis.ajax = Em.Object.create options.contentType = options.contentType || 'application/json; charset=utf-8' success = options.success || (->) - options.success = (data) => + options.success = (data, status, xhr) => Travis.lookup('controller:flash').loadFlashes(data.flash) if data?.flash delete data.flash if data? success.apply(this, arguments) error = options.error || (->) - options.error = (data) => + options.error = (data, status, xhr) => Travis.lookup('controller:flash').pushObject(data.flash) if data?.flash delete data.flash if data? error.apply(this, arguments) - $.ajax($.extend(options, Travis.ajax.DEFAULT_OPTIONS)) + options = $.extend(options, Travis.ajax.DEFAULT_OPTIONS) + + if options.data && (method == "GET" || method == "HEAD") + params = [] + for key, value of options.data + params.pushObject("#{key}=#{value}") + + params = params.join '&' + delimeter = if url.indexOf('?') == -1 then '?' else '&' + url = url + delimeter + params + + xhr = new XMLHttpRequest() + + xhr.open(method, url) + + if options.accepts + accepts = [] + for key, value of options.accepts + accepts.pushObject(value) + xhr.setRequestHeader('Accept', accepts.join(', ')) + + if options.headers + for name, value of options.headers + xhr.setRequestHeader(name, value) + + if options.contentType + xhr.setRequestHeader('Content-Type', options.contentType) + + xhr.onreadystatechange = -> + if xhr.readyState == 4 + contentType = xhr.getResponseHeader('Content-Type') + data = if contentType && contentType.match /application\/json/ + jQuery.parseJSON(xhr.responseText) + else + xhr.responseText + + if xhr.status >= 200 && xhr.status < 300 + options.success.call(options.context, data, xhr.status, xhr) + else + options.error.call(data, xhr.status, xhr) + + xhr.send(options.data)