2016-06-18 20 views
1

在我的Symfony 3.0.6應用程序中,某些常用路由在用戶註冊完成之前不可用。在完成之前,我使用AccessDeniedHandlerInterface將它們重定向到提示它們完成它的路線。我也使用閃光燈消息來解釋發生了什麼事:Chrome預取會導致重複的Flash消息

/** 
* Handles an access denied failure. 
* 
* @param Request $request 
* @param AccessDeniedException $accessDeniedException 
* 
* @return Response may return null 
*/ 
public function handle(Request $request, AccessDeniedException $accessDeniedException) 
{ 
    if (null === $token = $this->security->getToken()) { 
     return; 
    } 

    if (!is_object($user = $token->getUser())) { 
     return; 
    } 

    /** @var User $user */ 

    if (!$user->isFinalised()) { 
     $request->getSession()->getFlashBag()->add('info', 'You need to complete your registration before you can do this!'); 
     return new RedirectResponse($this->router->generate('app_registration_complete')); 
    } 

    return; 
} 

然而,問題與Chrome的預取/預渲染服務出現了 - Chrome是否決定一個URL有可能被訪問,將預取它。預取會導致上面的Flash消息被添加到用戶的會話中,因此後續頁面加載意味着顯示該消息。如果他們實際上去了一條他們尚未被允許訪問的路線,他們會看到兩條消息 - 一條在預取過程中產生,另一條在實際導航時產生。

this question中描述了類似的問題,但接受的答案(在註銷請求中使用POST)在這種情況下似乎並不是正確的解決方案。 Flash消息更多地是對重定向的一個解釋性附加說明,而不是改變應用程序狀態的東西。此外,用戶可能會通過多種方式訪問​​這些不允許的路由之一,我無法將所有這些轉換爲觸發POST,只是爲了在某些情況下避開預取問題。

那麼...我該如何處理這個問題呢?

回答

-1

我看到您的代碼有一個問題。你應該改變爲:

if (null === $this->security->getToken()) { 
    return; 
} 

我不認爲這將解決問題,但。

+0

嗨Alvin,恐怕你錯了 - 「=」運算符的優先級高於「===」。運行'var_dump(null === $ a = null);'看看它在行動。 – Alex

+0

感謝您指出了亞歷克斯。你是對的。我從代碼中看到它也可能初始化變量$ token。我的錯誤 - 對不起。 –