Arpit Vaishnav
Arpit Vaishnav

Reputation: 4780

Rails 4: Turbolinks sends request twice and reloads the page

I am working on on a Ruby on Rails application using Rails 4.1.1 and Ruby 2.1.0.

I have set up the app to use Turbolinks, which is causing an issue with AJAX links. When I click on a link that calls an AJAX function three things happen:
1. The AJAX call is made
2. The same link is reloaded
3. The application server runs all the requests twice.

How can I make these links function as standard AJAX links?

For reference, here is the relevant portion of my GemFile:

gem 'turbolinks'
gem 'jquery-turbolinks'

Here is how I included the JavaScript libraries in application.js:

//= require jquery
//= require jquery.turbolinks
//= require jquery_ujs
//= require turbolinks

And here is how I included the JavaScript files in the application layout:

<%= stylesheet_link_tag 'application', media: 'all', 'data-turbolinks-track' => true %>
<%= javascript_include_tag 'application', 'data-turbolinks-track' => true %>

Upvotes: 3

Views: 1678

Answers (2)

Oscar Jiang
Oscar Jiang

Reputation: 305

There might be 3 reasons:

  • Your response status to that request is between 400 and 600
  • Your response content type does not match /^(?:text\/html|application\/xhtml\+xml|application\/xml)(?:;|$)/
  • The assets has changed in new page. For example, you render a new page in a different layout which includes another js. When data-turbolinks-track is true, turbolinks will do a refreshment.

The 3 reasons can be got from source code below. When response gives doc body, it will show it, or it will refresh page.

fetchReplacement = (url, onLoadFunction, showProgressBar = true) ->
  ...
  xhr.onload = ->
    triggerEvent EVENTS.RECEIVE, url: url.absolute
    if doc = processResponse()
      reflectNewUrl url
      reflectRedirectedUrl()
      changePage extractTitleAndBody(doc)...
      manuallyTriggerHashChangeForFirefox()
      onLoadFunction?()
      triggerEvent EVENTS.LOAD
    else
      document.location.href = crossOriginRedirect() or url.absolute

processResponse = ->
  clientOrServerError = ->
    400 <= xhr.status < 600

  validContent = ->
    (contentType = xhr.getResponseHeader('Content-Type'))? and
      contentType.match /^(?:text\/html|application\/xhtml\+xml|application\/xml)(?:;|$)/

  ...

  //here is the check
  if not clientOrServerError() and validContent()
    doc = createDocument xhr.responseText
    if doc and !assetsChanged doc
      return doc

Upvotes: 8

Zakaria Boualaid
Zakaria Boualaid

Reputation: 9

Try to use :onsubmit => "false" in your forms, and use click function to run your submits.

Upvotes: -2

Related Questions