2017-10-07 53 views
1

我有一個登錄頁面,可以在其上進行身份驗證,也可以不成功登錄。這裏是頁new.html.erbhttp發佈失敗後瀏覽器URL更改

<%=form_with scope: :session, url: sessions_path, local: true, html: {class: "login-form"} do |f| %> 
    <%= f.label :email, t("session.new.email") %> 
    <%= f.email_field :email %> 

    <%= f.label :password, t("session.new.password") %> 
    <%= f.password_field :password %> 

    <%= f.submit t('session.new.login'), class: "submit" %> 
<% end %> 

它關聯到sessions_controller.rb,這是這樣的:

class SessionsController < ApplicationController 

    def create 
    # Find the user with the matching email 
    user = User.find_by(email: params[:session][:email].downcase) 

    # Check the user exists in DB and that the provided password matches 
    if user && user.authenticate(params[:session][:password]) 
     # Log the user through the session helper 
     log_in user 
     # Redirect to the hive 
     redirect_to ideas_path 
    else 
     # The authentication failed. Display an error message 
     flash.now[:error] = I18n.t('session.new.invalid_credentials') 
     # The render is done to reinitiate the page 
     render :new 
    end 
    end 
end 

在我routes.rb,我只是爲了這個目的:

resources :sessions 

執行rails routes時,我有以下申報路線:

Routes

現在我的問題是登錄失敗。在我的控制器中,在這種情況下,我在閃光消息中添加一條消息,然後重新渲染同一頁面new.html.erb。但是在瀏覽器中,登錄請求POST已經在URL /sessions上發送。問題是我的瀏覽器上的當前網址變爲/sessions,而不是停留在/sessions/new。這就好像POST請求在我的瀏覽器中更改了URL一樣。但這實際上只是一個AJAX請求,不是嗎?

我發現這是blog post懷疑這個現象是相同的(我不是作者)

我已經找到了解決辦法,但我會用它傾向於規避和了解bevahior。如果我通過以下取代我的路線,這個工程:

get '/login', to: 'sessions#new' 
post '/login', to: 'sessions#create' 

我能理解爲什麼這個作品:GET和POST網址是相同的,所以瀏覽器不改變它的URL。

你有什麼想法嗎?

編輯:

我終於找到了解決辦法。我不確定這是否是「鐵軌方式」,但這是按預期工作的。我剛換了控制器做一個重定向到同一頁面,用閃光燈傳送請求登錄失敗的信息:

def create 
    # Find the user with the matching email 
    user = User.find_by(email: params[:session][:email].downcase) 

    # Check the user exists in DB and that the provided password matches 
    if user && user.authenticate(params[:session][:password]) 
    # Log the user through the session helper 
    log_in user 
    # Redirect to the hive 
    redirect_to ideas_path 
    else 
    # The authentication failed. Display an error message through a flash 
    # message after redirect to the same page 
    redirect_to new_session_path, alert: I18n.t('session.new.invalid_credentials') 
    end 
end 

回答

2

當表單被提交瀏覽器執行常規HTTP POST requsest到/會話端點。沒有AJAX那裏。

您的路線配置方式此POST請求將由您的會話#create action處理。

注意那裏的代碼。你會看到快樂的路徑(成功登錄)呼叫redirect_to。如果出現登錄錯誤,控制器會調用render

區別在於,在第一種情況下,響應是瀏覽器所遵循的302重定向。這就是您在瀏覽器中看到URL更改的原因。在第二種情況下,瀏覽器呈現一堆HTML時,響應僅爲200 OK。該URL不會改變,因爲瀏覽器沒有被指示在別處導航。

如果您有興趣,請在瀏覽器中輸入extensive explanation of how redirects work

+0

感謝您的回答和相關文檔。我錯過了一點:爲什麼我提交POST請求時,瀏覽器的URL會發生變化?我認爲這隻適用於GET請求。此外,RoR對我的用例有什麼好的方法? –

+1

一直在試圖找到一些適當的文檔,這將比我更好地解釋它,但沒有運氣。瀏覽器訪問'/ sessions/new'。然後你提交表單,所以瀏覽器知道的最後一個URL是'/ sessions'。這是從服務器上提出的「資源」。服務器響應,並且由於它不重定向,瀏覽器將使用該URL。打開瀏覽器中的開發工具並檢查服務器響應。響應URL是'/ sessions',對吧?希望它是有道理的:/ – gkats

+0

是的,你的回答幫助我理解。現在,我只需要了解如何正確使用Rails,以便我可以達到我的目標:) –