简体   繁体   English

Ruby On Rails before_filter调用过两次吗?

[英]Ruby On Rails before_filter called twice?

When I send an ajax request to my ruby controller, the before_filter function seems to be called twice for each ajax request. 当我向我的ruby控制器发送一个ajax请求时,似乎对每个ajax请求都调用了before_filter函数两次。 I use the before_filter for authentication. 我使用before_filter进行身份验证。

The ajax request I use : 我使用的ajax请求

 $.ajax({
    type: 'GET',
    url: 'URL_TO__RoR_Controller',
    username: username,
    password: password,
    contentType: "application/json; charset=utf-8",
    success: function(data){
      console.log(data);
    },
    error: function(xhr, ajaxOptions, thrownError) {
      console.log(arguments);
    }
  });

The RoR code : RoR代码

class Api::MyController < ApplicationController
before_filter :authenticate
attr_reader :current_user

def authenticate
print "===================================\n"
authenticate_or_request_with_http_basic do |username, password|
  print "\n--------------------------------\n"
  print username, password
  print "\n--------------------------------\n"
  @current_user = User.authenticate(username, password)
  print "===================================\n"
end
end

def show
 print "=================IN SHOW=================="
end
end

The RoR response to the ajax request : RoR对ajax请求的响应

Started GET "URL_TO__RoR_Controller" for 127.0.0.1 at 2015-10-08 10:18:18 +0200
Processing by Api::MyController#show as JSON
  Parameters: {"id"=>"show", "test"=>{}}
===================================
===================================
Filter chain halted as :authenticate rendered or redirected
Completed 401 Unauthorized in 1ms (ActiveRecord: 1.0ms)


Started GET "URL_TO__RoR_Controller" for 127.0.0.1 at 2015-10-08 10:18:19 +0200
Processing by Api::MyController#show as JSON
  Parameters: {"id"=>"show", "test"=>{}}
===================================

--------------------------------
USERPASS
--------------------------------
  User Load (0.2ms)  SELECT `users`.* FROM `users` WHERE `users`.`authorized` = 1 AND `users`.`login` = 'USER' LIMIT 1
===================================
=================IN SHOW==================
  Rendered URL_TO__RoR_Controller/show.json.rabl (0.8ms)
Completed 200 OK in 30ms (Views: 3.4ms | ActiveRecord: 1.7ms)

RoR config/routes.rb for this single controller : 该单个控制器的RoR config / routes.rb

Api::Application.routes.draw do
 namespace :api, defaults: { format: :json } do
      resources :MyController, only: [:show]
  end
 end

So basically the authenticate function seems to be executed twice for each ajax request I send. 因此,基本上,对于我发送的每个ajax请求,authenticate函数似乎都会执行两次。 The first time authentication seems to fail. 首次身份验证似乎失败。 It doesn't even get in the authenticate_or_request_with_http_basic function. 它甚至没有进入authenticate_or_request_with_http_basic函数。 The second time everything seems fine. 第二次似乎一切正常。

Obviously this is not the desired behaviour. 显然,这不是期望的行为。 What is causing this problem? 是什么导致此问题?

Edit: 编辑:

Okay here are my findings when removing the before_filter: 好的,这是删除before_filter时的发现:

1) When Removing the before_filter completely the issue doesn't occur anymore. 1)当完全删除before_filter时,此问题不再发生。

2) When keeping/using the before_filter but replacing the authenticate_or_request_with_http_basic with 'true' like this: 2)当保留/使用before_filter但用'true'替换authenticate_or_request_with_http_basic时,如下所示:

def authenticate
 true
end 

the issue doesn't occur either. 这个问题也不会发生。 So the issue seems to be caused by authenticate_or_request_with_http_basic? 因此,问题似乎是由authenticate_or_request_with_http_basic引起的吗?

This won't happen unless it's invoked somehow. 除非以某种方式调用它,否则不会发生。

And seeing that the requests are sent 1 second between each other, it suggests that your Ajax is being sent twice: 并且看到请求之间相互发送了1秒,这表明您的Ajax被发送了两次:

127.0.0.1 at 2015-10-08 10:18:18 +0200
127.0.0.1 at 2015-10-08 10:18:19 +0200

Whilst this is not an answer in itself, there are a number of things you can do to "debug" it: 虽然这本身并不是一个答案,但是您可以执行许多操作来“调试”它:

  1. Firstly, you must understand this will not happen on its own 首先,您必须了解这不会自己发生
  2. The "debug" process is simply a case of identifying what's happening & resolving it “调试”过程只是识别正在发生的事情并解决它的一种情况
  3. I don't think Rails will fire a controller action twice without it being invoked 我不认为Rails会在不被调用的情况下触发两次控制器操作

Thus, you have to look at the various elements of the problem: 因此,您必须查看问题的各个要素:


Firstly, your Ajax request seems to be fired twice. 首先,您的Ajax请求似乎被触发了两次。

You've provided the following code: 您提供了以下代码:

$.ajax({
    type: 'GET',
    url: 'URL_TO__RoR_Controller',
    username: username,
    password: password,
    contentType: "application/json; charset=utf-8",
    success: function(data){
      console.log(data);
    },
    error: function(xhr, ajaxOptions, thrownError) {
      console.log(arguments);
    }
});

This does not show us how it's bound to the elements on your page. 没有向我们展示它如何绑定到页面上的元素。 I'd speculate that you're running into issues with Turbolinks. 我推测您正在遇到Turbolinks的问题。

The first step to debug is to ensure that your JS binding is not impeded. 调试的第一步是确保不妨碍JS绑定。 Specifically, you want to make sure you're taking advantage of the turbolinks hooks ( page:load ): 具体来说,您要确保您利用了turbolinks挂钩page:load ):

#app/assets/javascripts/application.js
bind = function() {
   $(".element").on("click", function() {
      // Ajax
   });
};
$(document).on("ready page:load", bind);

Or you could delegate from the document: 或者,您可以从文档中委派:

#app/assets/javascripts/application.js
$(document).on("click", ".element", function() {
     // Ajax
});

Secondly, your controller actions appear to be invoked twice, but it's not just the before_filter ... it's the whole flow (in the second instance). 其次,您的控制器动作似乎被调用了两次,但这不只是before_filter ...而是整个流程(在第二个实例中)。

Filter chain halted as :authenticate rendered or redirected
Completed 401 Unauthorized in 1ms (ActiveRecord: 1.0ms)

The only reason the first before_filter didn't fire was because you weren't authenticated. 第一个before_filter不触发的唯一原因是因为您未经身份验证。 I don't know how you're authenticating users, but if you were able to do it, I would think that the flow would happen. 我不知道您如何验证用户身份,但是如果您能够做到这一点,我认为流程将会发生。

So the question then becomes how are you getting the first request bounced ? 那么问题就变成了如何使第一个请求退回

If you're doing anything differently between the two requests, we need to see it. 如果您在两个请求之间做任何不同的事情,我们需要查看它。 Not that I think you'd know, it's doing it automatically :) 不是我想您会知道的,它是自动执行的:)

-- -

This could be backed up by observing the "network" requests sent to the server with the ajax: 这可以通过观察用ajax 发送到服务器“网络”请求来备份:

在此处输入图片说明


Finally, you want to do some tests without the before_filter method to see if that will work. 最后,您需要在没有before_filter方法的情况下进行一些测试,以查看是否可行。 Perhaps you've not got the correct authenticity tokens or another issue within the middleware. 也许您在中间件中没有正确的真实性令牌或其他问题。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM