diff --git a/src/rails.js b/src/rails.js index 4dcb3779..671a3236 100644 --- a/src/rails.js +++ b/src/rails.js @@ -12,6 +12,10 @@ obj.trigger(event, data); return event.result !== false; } + + function appendCsrfToken(xhr){ + xhr.setRequestHeader('X-CSRF-Token', $('meta[name=csrf-token]').attr('content')); + } // Submits "remote" forms and links with ajax function handleRemote(element) { @@ -41,6 +45,7 @@ if (settings.dataType === undefined) { xhr.setRequestHeader('accept', '*/*;q=0.5, ' + settings.accepts.script); } + appendCsrfToken(xhr); return fire(element, 'ajax:beforeSend', [xhr, settings]); }, success: function(data, status, xhr) { @@ -137,7 +142,7 @@ var name = button.attr('name'), data = name ? {name:name, value:button.val()} : null; button.closest('form').data('ujs:submit-button', data); }); - + $('form').live('ajax:beforeSend.rails', function(event) { if (this == event.target) disableFormElements($(this)); }); @@ -145,4 +150,11 @@ $('form').live('ajax:complete.rails', function(event) { if (this == event.target) enableFormElements($(this)); }); + + $.ajaxSetup({ + beforeSend: function(xhr){ + appendCsrfToken(xhr); + } + }); })( jQuery ); + diff --git a/test/public/test/call-remote-callbacks.js b/test/public/test/call-remote-callbacks.js index d1ae79fa..553c10af 100644 --- a/test/public/test/call-remote-callbacks.js +++ b/test/public/test/call-remote-callbacks.js @@ -99,7 +99,13 @@ asyncTest('"ajax:beforeSend", "ajax:error" and "ajax:complete" are triggered on form.bind('ajax:error', function(e, xhr, status, error) { equal(typeof xhr.getResponseHeader, 'function', 'first argument to "ajax:error" should be an XHR object'); equal(status, 'error', 'second argument to ajax:error should be a status string'); - equal(error, 'Forbidden', 'third argument to ajax:error should be an HTTP status response'); + //1.4 sends an undefined error so use the status text + if(error != null){ + equal(error, 'Forbidden', 'third argument to ajax:error should be an HTTP status response'); + } + else { + equal(xhr.statusText, 'Forbidden', 'status text should be Forbidden') + } // Opera returns "0" for HTTP code equal(xhr.status, window.opera ? 0 : 403, 'status code should be 403'); }); diff --git a/test/public/test/call-remote.js b/test/public/test/call-remote.js index 90fd0154..771d87b7 100644 --- a/test/public/test/call-remote.js +++ b/test/public/test/call-remote.js @@ -67,6 +67,19 @@ asyncTest('prefer JS, but accept any format', 1, function() { }); }); +asyncTest('passes in csrf token', 1, function(){ + build_form({ method: 'post', action: '/header' }) + + $("form").append($("").attr("name", "key").val("X-CSRF-Token")); + $('#qunit-fixture') + .append('') + .append(''); + + submit(function(e, data, status, xhr){ + equal(data, $('meta[name=csrf-token]').attr('content')); + }) +}) + asyncTest('accept application/json if "data-type" is json', 1, function() { build_form({ method: 'post', 'data-type': 'json' }); diff --git a/test/public/test/settings.js b/test/public/test/settings.js index 616ebc68..0ecd2a0e 100644 --- a/test/public/test/settings.js +++ b/test/public/test/settings.js @@ -27,6 +27,10 @@ App.assert_request_path = function(request_env, path) { equal(request_env['PATH_INFO'], path, 'request should be sent to right url'); }; +App.assert_header_value = function(body, expected_value) { + equal(body, expected_value) +} + // hijacks normal form submit; lets it submit to an iframe to prevent // navigating away from the test suite $(document).bind('submit', function(e) { diff --git a/test/server.rb b/test/server.rb index 32340521..760511a7 100644 --- a/test/server.rb +++ b/test/server.rb @@ -56,3 +56,13 @@ def script_tag src get '/error' do status 403 end + +post '/header' do + status 200 + header_key = "HTTP_#{params[:key].upcase.gsub("-", "_")}" + if env[header_key] + env[header_key] + else + "" + end +end \ No newline at end of file