繁体   English   中英

Ruby on Rails-多个POST请求

[英]Ruby on Rails - Multiple POST requests

下午好,

我有一个内部的ruby on rails(4.1.14)应用程序运行在passenger / nginx上,并为其分配了3个进程。 偶尔(少于5%的时间)我从一个提交操作中获得多个POST。 日志如下所示:

1)用户使用Google Chrome浏览器访问build_item_interaction#new。 这产生了3个(!)GET请求。

I, [2017-02-14T13:27:49.679558 #19777]  INFO -- : Started GET "/build_item_interactions/new?serial_number=1702R022&type=end_of_line" for 192.168.45.105 at 2017-02-14 13:27:49 -0600
I, [2017-02-14T13:27:49.681263 #19777]  INFO -- : Processing by BuildItemInteractionsController#new as HTML
I, [2017-02-14T13:27:49.681354 #19777]  INFO -- :   Parameters: {"serial_number"=>"1702R022", "type"=>"end_of_line"}
I, [2017-02-14T13:27:49.690776 #19777]  INFO -- :   Rendered build_item_interactions/_new_interaction.html.erb (4.7ms)
I, [2017-02-14T13:27:49.690956 #19777]  INFO -- :   Rendered build_item_interactions/new.html.erb within layouts/application (5.1ms)
I, [2017-02-14T13:27:49.693310 #19777]  INFO -- :   Rendered layouts/_login_header.html.erb (1.4ms)
I, [2017-02-14T13:27:49.693779 #19777]  INFO -- : Completed 200 OK in 12ms (Views: 8.6ms | ActiveRecord: 1.0ms)
I, [2017-02-14T13:27:49.712790 #19777]  INFO -- : Started GET "/build_item_interactions/new?serial_number=1702R022&type=end_of_line" for 192.168.45.105 at 2017-02-14 13:27:49 -0600
I, [2017-02-14T13:27:49.714741 #19777]  INFO -- : Processing by BuildItemInteractionsController#new as HTML
I, [2017-02-14T13:27:49.714852 #19777]  INFO -- :   Parameters: {"serial_number"=>"1702R022", "type"=>"end_of_line"}
I, [2017-02-14T13:27:49.722208 #19777]  INFO -- :   Rendered build_item_interactions/_new_interaction.html.erb (3.5ms)
I, [2017-02-14T13:27:49.722370 #19777]  INFO -- :   Rendered build_item_interactions/new.html.erb within layouts/application (3.8ms)
I, [2017-02-14T13:27:49.724351 #19777]  INFO -- :   Rendered layouts/_login_header.html.erb (1.2ms)
I, [2017-02-14T13:27:49.724693 #19777]  INFO -- : Completed 200 OK in 10ms (Views: 6.4ms | ActiveRecord: 0.7ms)
I, [2017-02-14T13:27:49.746169 #19777]  INFO -- : Started GET "/build_item_interactions/new?serial_number=1702R022&type=end_of_line" for 192.168.45.105 at 2017-02-14 13:27:49 -0600
I, [2017-02-14T13:27:49.747577 #19777]  INFO -- : Processing by BuildItemInteractionsController#new as HTML
I, [2017-02-14T13:27:49.747658 #19777]  INFO -- :   Parameters: {"serial_number"=>"1702R022", "type"=>"end_of_line"}
I, [2017-02-14T13:27:49.754470 #19777]  INFO -- :   Rendered build_item_interactions/_new_interaction.html.erb (3.6ms)
I, [2017-02-14T13:27:49.754647 #19777]  INFO -- :   Rendered build_item_interactions/new.html.erb within layouts/application (3.9ms)
I, [2017-02-14T13:27:49.756809 #19777]  INFO -- :   Rendered layouts/_login_header.html.erb (1.3ms)
I, [2017-02-14T13:27:49.757209 #19777]  INFO -- : Completed 200 OK in 9ms (Views: 6.9ms | ActiveRecord: 0.7ms)

2)然后,用户单击页面上的[Submit]按钮,该按钮会产生2个连续的POST请求:

I, [2017-02-14T13:27:59.692934 #19777]  INFO -- : Started POST "/build_item_interactions?serial_number=1702R022&type=end_of_line" for 192.168.45.105 at 2017-02-14 13:27:59 -0600
I, [2017-02-14T13:27:59.693996 #19777]  INFO -- : Processing by BuildItemInteractionsController#create as HTML
I, [2017-02-14T13:27:59.694105 #19777]  INFO -- :   Parameters: {"utf8"=>"?", "authenticity_token"=>"FFs8Uh07oKpvZ57wHzTll/PQxVp0eaK3bVIsOKUDGPU=", "build_item_interaction"=>{"build_item_id"=>"4501
", "interaction_type_id"=>"5", "data"=>"", "badge"=>["SuxY3ATMMjs"]}, "commit"=>"Save Checkpoint", "serial_number"=>"1702R022", "type"=>"end_of_line"}
I, [2017-02-14T13:27:59.708826 #19777]  INFO -- : Redirected to http://fbdbms/build_items/4501
I, [2017-02-14T13:27:59.709030 #19777]  INFO -- : Completed 302 Found in 15ms (ActiveRecord: 7.0ms)
I, [2017-02-14T13:27:59.733202 #19777]  INFO -- : Started POST "/build_item_interactions?serial_number=1702R022&type=end_of_line" for 192.168.45.105 at 2017-02-14 13:27:59 -0600
I, [2017-02-14T13:27:59.734318 #19777]  INFO -- : Processing by BuildItemInteractionsController#create as HTML
I, [2017-02-14T13:27:59.734412 #19777]  INFO -- :   Parameters: {"utf8"=>"?", "authenticity_token"=>"FFs8Uh07oKpvZ57wHzTll/PQxVp0eaK3bVIsOKUDGPU=", "build_item_interaction"=>{"build_item_id"=>"4501
", "interaction_type_id"=>"5", "data"=>"", "badge"=>["SuxY3ATMMjs"]}, "commit"=>"Save Checkpoint", "serial_number"=>"1702R022", "type"=>"end_of_line"}
I, [2017-02-14T13:27:59.747852 #19777]  INFO -- : Redirected to http://fbdbms/build_items/4501
I, [2017-02-14T13:27:59.748100 #19777]  INFO -- : Completed 302 Found in 14ms (ActiveRecord: 5.7ms)

3)创建两个记录,然后用户被转发到资源的“所有者”页面:

I, [2017-02-14T13:27:59.756761 #19777]  INFO -- : Started GET "/build_items/4501" for 192.168.45.105 at 2017-02-14 13:27:59 -0600
I, [2017-02-14T13:27:59.757784 #19777]  INFO -- : Processing by BuildItemsController#show as HTML
I, [2017-02-14T13:27:59.757850 #19777]  INFO -- :   Parameters: {"id"=>"4501"}
I, [2017-02-14T13:27:59.809268 #19777]  INFO -- :   Rendered shared/_rfid_scans_table.html.erb (0.1ms)
I, [2017-02-14T13:27:59.809422 #19777]  INFO -- :   Rendered build_items/show.html.erb within layouts/application (41.4ms)
I, [2017-02-14T13:27:59.811722 #19777]  INFO -- :   Rendered layouts/_login_header.html.erb (1.3ms)
I, [2017-02-14T13:27:59.812213 #19777]  INFO -- : Completed 200 OK in 54ms (Views: 12.3ms | ActiveRecord: 35.6ms)

控制器中的相关代码如下所示:

class BuildItemInteractionsController < ApplicationController
    def new
        load_build_item
        load_interaction_info
        if @interaction_info then
            @interaction = BuildItemInteraction.new( build_item_id: @build_item.try(:id), 
                                                     interaction_type_id: @interaction_info[:id] )
        end
    end
    def create
        load_build_item
        load_interaction_info
        badge = params[:build_item_interaction][:badge]
        user  = Badge.valid_badge(badge)

        @interaction = BuildItemInteraction.new(params_for_interaction)
        @interaction.user = user
        if @interaction.save then
            flash[:success] = "Record saved"
            redirect_to @interaction.build_item
        else    
            err = @interaction.errors.full_messages
            flash.now[:danger] = "Could not save record: #{err}"
            render "new"
        end
    end
    private
        def load_interaction_info
            @interactions = { "teardown"    => { id: 9, description: "End of Teardown"  },
                          "sta4"        => { id: 6, description: "End of Station 4" },
                          "sta7"        => { id: 7, description: "End of Station 7" },
                          "sta8"        => { id: 8, description: "End of Test" },
                          "end_of_line" => { id: 5, description: "End of Line" } }
            interaction_type = params[:type]
            @interaction_info = @interactions[interaction_type]
        end
        def load_build_item
            sn = params[:serial_number]
            @build_item = BuildItem.where(serial_number: sn).first
        end
        def params_for_interaction
            params.require(:build_item_interaction).permit(:build_item_id, :interaction_type_id, :badge, :data)
        end
end

表单代码如下所示:

<h2><%= @interaction_info[:description] %> Scan for <%= @build_item.serial_number%></h2>

<p><%= link_to("Back to Unit Record", @build_item) %></p>

<div class="well">
    <%= simple_form_for(@interaction,
                        :url  => build_item_interactions_path(type: "end_of_line", serial_number: @build_item.serial_number),
                        :html => { :class => "form-horizontal" },
                        wrapper: :horizontal_form,
                        wrapper_mappings: {
                            check_boxes:   :horizontal_radio_and_checkboxes,
                            radio_buttons: :horizontal_radio_and_checkboxes,
                            file: :horizontal_file_input,
                            boolean: :horizontal_boolean}) do |f| %>
        <%= f.association :build_item,       as: :hidden %>
        <%= f.association :interaction_type, as: :hidden %>
        <%= f.input       :data, label: "Comments", as: :text %>


        <div class="form-group select required build_item_interaction_badge">
            <label class="select required col-sm-3 control-label" for="build_item_interaction_badge">
                <abbr title="required">*</abbr>Badge
            </label>
            <div class="col-sm-9">
                <%= password_field "build_item_interaction[badge]", nil, class: "string required form-control",
                                                                            id: "build_item_interaction_badge",
                                                                            placeholder: "XXXXXXXXXXXX" %>
                </div>
        </div>
        <div class="text-center">
            <%= f.submit "Save Checkpoint",  data: {disable_with: "Saving..."} %>
        </div>
    <% end %>
</div>

我不知道为什么我最终会收到2x POST请求。 我尝试做的一些事情:

1)将数据:{disable_with:“正在保存...”}添加到提交按钮。 单击后似乎可以使用(它会变灰/禁用按钮)。

2)我已经阅读了CSRF令牌。 看起来,此令牌的存在应足以防止第二个请求被处理。 las-日志显示,两个请求都使用相同的authentication_token命中了0.1秒,我得到了两个新记录。

有什么建议么?

更新:我检查了nginx访问日志,nginx也正在处理多个请求:

192.168.45.105 - - [14/Feb/2017:13:27:49 -0600] "GET /build_item_interactions/new?serial_number=1702R022&type=end_of_line HTTP/1.1" 499 0 "http://fbdbms/build_items/4501" "Mozilla/5.0 (Windows NT 6
.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/56.0.2924.87 Safari/537.36" "-"
192.168.45.105 - - [14/Feb/2017:13:27:49 -0600] "GET /build_item_interactions/new?serial_number=1702R022&type=end_of_line HTTP/1.1" 200 1657 "http://fbdbms/build_items/4501" "Mozilla/5.0 (Windows N
T 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/56.0.2924.87 Safari/537.36" "-"
192.168.45.105 - - [14/Feb/2017:13:27:49 -0600] "GET /build_item_interactions/new?serial_number=1702R022&type=end_of_line HTTP/1.1" 200 1657 "http://fbdbms/build_items/4501" "Mozilla/5.0 (Windows N
T 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/56.0.2924.87 Safari/537.36" "-"
192.168.45.105 - - [14/Feb/2017:13:27:59 -0600] "POST /build_item_interactions?serial_number=1702R022&type=end_of_line HTTP/1.1" 302 107 "http://fbdbms/build_item_interactions/new?serial_number=170
2R022&type=end_of_line" "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/56.0.2924.87 Safari/537.36" "-"
192.168.45.105 - - [14/Feb/2017:13:27:59 -0600] "POST /build_item_interactions?serial_number=1702R022&type=end_of_line HTTP/1.1" 302 107 "http://fbdbms/build_item_interactions/new?serial_number=170
2R022&type=end_of_line" "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/56.0.2924.87 Safari/537.36" "-"

多个GET请求可能与此处的 Chrome浏览器的预测性浏览功能有关 很好,但是多个POST是问题所在。

这是导致罪魁祸首的原因

浏览器 :如果您使用的是Chrome。 按F12键(Ctrl + Shift + c)检查您的浏览器的“ Network选项卡,以查看浏览器针对GETPOST请求发送了多少个请求。 如果仅看到一个,则浏览器或前端不是问题

Nginx :检查您的Nginx access logs ,其中显示了到达服务器的所有请求。 如果这正在打印多个请求,那么我怀疑浏览器和服务器之间存在某种原因,这可能是Load Balancer 不知道您的设置中是否包含LB。 如果这不打印多个请求,则显然与Nginx或Passenger配置有关,这导致重复请求并发送到您的Rails服务器

暂无
暂无

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

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