在我的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
,只是为了在某些情况下避开预取问题。
那么...我该如何处理这个问题呢?
嗨Alvin,恐怕你错了 - “=”运算符的优先级高于“===”。运行'var_dump(null === $ a = null);'看看它在行动。 – Alex
感谢您指出了亚历克斯。你是对的。我从代码中看到它也可能初始化变量$ token。我的错误 - 对不起。 –