2015-05-16 46 views
2

任何用戶都可以在我的網站上「喜歡」照片。但是如果他多次按下該按鈕(例如10),則10個發佈請求將被髮送到服務器。 我試圖在會議的幫助下解決。 我認爲這段代碼每5秒鐘只需要一次。但它沒有!還有我的行動和的before_filter:如何保護我的網站免受多個帖子的要求?

def like 
    photo.create_like if session[:voted].nil? 
    session[:voted] = Time.now.to_a.first(3).reverse.join 
    redirect_to root_path 
end 


def check_session 
    a = Time.now.to_a.first(3).reverse.join 
    b = a.to_i - session[:voted].to_i 
    session[:voted] = nil if b >= 5 

end 
+0

如何使用JavaScript禁用提交按鈕? –

+0

您可以在'likes'上創建數據庫級別的「唯一約束」,僅強制一對照片用戶存在。限制界面是不可靠的,請求僞造仍然是可能的。改爲限制底層模型。我不會把這個作爲答案發布,因爲我不完全知道這是否適合你的邏輯。即如果你根本沒有'User'。 –

回答

2

你不能用會話做到這一點(至少不用默認的會話存儲):默認情況下,rails會將會話存儲在cookie中。

Cookie由瀏覽器發送,作爲請求的一部分,服務器的響應可以選擇更新它們。如果您連續幾次點擊您喜歡的按鈕,那麼您將觸發多個請求,每個請求都包含代表當前會話狀態的Cookie數據。您的響應會更新會話,但對於已發送的請求來說太遲了 - 它們的會話數據已經發送到服務器,並且不會包含響應所做的任何更改。

正如其他人所說,bandaid是使用Javascript來限制多次提交,但唯一可靠的方式來處理這是在數據庫級別(在喜歡的表上有一個唯一的索引)。

1

你在你的like方法忘記reverse,因此比較不工作。它應該是:

session[:voted] = Time.now.to_a.first(3).reverse.join 

此外,在like你使用session[:voted]check_session你使用session[:time]

雖然這也不能正常工作。爲此使用Unix時間戳會更好,並讓check_session返回一個布爾值。事情是這樣的:

def like 
    photo.create_like if check_session 
    session[:voted] = Time.now.to_i 
    redirect_to root_path 
end 

def check_session 
    session[:voted].blank? || (Time.now.to_i - session[:voted]) > 5 
end 
+0

Thx爲您提供幫助,但我不小心從我的項目中複製了代碼。這是你描述的錯誤的原因。 但是。我照你說的做了,沒有任何改變。 10個快速點擊按鈕讓我在照片上有10個喜歡。 – Alexander

0

<%= submit_tag "Login", 'data-disable-with' => "Please wait.." %> 禁用按鈕你可以在你的意見添加一個條件以示投票或要投票?如果用戶投票已經

相關問題