2016-06-18 19 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。我的错误 - 对不起。 –