Rails技术问题:onchange事件触发后页面为何自动重定向?
Hey Mike, let's break down why you're seeing this unexpected redirect even without a respond_to block—this is a super common gotcha with Rails UJS and form behavior!
1. You’re not stopping the browser’s default behavior
When you trigger an action on a select element (especially if it’s nested inside a form), the browser might fire its default HTML behavior (like submitting the form) on top of your JavaScript request. That’s exactly why you see two requests in the console: your JS runs first, then the browser follows through with its default redirect/submit.
Fix this by explicitly blocking the default action in your onchange handler:
document.getElementById('your-select-id').addEventListener('change', function(event) { // Stop the browser from doing its default HTML redirect/submit event.preventDefault(); // Your existing AJAX logic here fetch('/your-target-endpoint', { method: 'GET', headers: { 'Accept': 'text/javascript' } // Tell Rails you want a JS response }); });
If you’re using Rails form helpers, leverage remote: true on the select or parent form—this tells Rails UJS to handle the request as AJAX and block default behavior automatically:
<%= form_with(model: @your_model, remote: true) do |f| %> <%= f.select :your_field, options_for_select(YourModel.options), {}, onchange: "this.form.requestSubmit()" %> <% end %>
2. Your AJAX request isn’t specifying the right response format
Even with JS, if your request doesn’t tell Rails you want a JavaScript (or JSON) response, Rails will default to returning HTML. If your controller action uses redirect_to, that HTML response will trigger a full page redirect.
Double-check that your JS request includes the Accept: text/javascript header (or application/json if you’re expecting JSON data). Rails uses this header to determine which response format to send back.
3. The select is triggering an accidental form submit
Sometimes, onchange handlers accidentally trigger a standard form submit (like using this.form.submit() instead of Rails UJS’s requestSubmit()). If the form doesn’t have remote: true, this will fire a full HTML submission, leading to the redirect.
Make sure any form submission from the onchange handler uses Rails UJS-compatible methods, or explicitly prevents the default action as noted earlier.
Quick recap of the issue
Your JavaScript runs and sends a request, but since the browser’s default behavior isn’t blocked, it immediately sends a second HTML request. Even without a respond_to block, Rails defaults to HTML responses—so if your controller action includes a redirect_to, the browser will follow that redirect after the initial JS request.
内容的提问来源于stack exchange,提问作者mike

