Laravel Ajax登录,成功后重定向到先前的URL

7
假设我有一个页面A,使用了auth中间件。因为没有登录,所以它会被重定向到登录页面。
在登录页面上,我有一个自定义的ajax登录系统。登录成功后,我想重定向到具有相同url的页面A,以便可以完成操作。
我的登录代码如下:
public function postLogin(Request $request)
{

    $auth = false;
    $errors = [];

    $inputs = $request->all();
    $validator = $this->validator($inputs);

    if ($validator->fails()) {
        return response()->json([
            'auth' => false,
            'intended' => URL::previous(),
            'errors' => $validator->errors()
        ]);
    }

    $user = User::where('email', $request->get('email'))->first();

    if ($user && $user->is_active == 0) {
        $errors[] = "This account has been deactivated";
    } else if ($user && $user->confirm_token != null) {
        $errors[] = "Please verify your email in order to login";
    } else {

        $credentials = ['email' => $request->get('email'), 'password' => $request->get('password'), 'is_active' => 1];

        if (Auth::attempt($credentials, $request->has('remember'))) {
            $auth = true;
        } else {
            $errors[] = "Email/Password combination not correct";
        }

    }

    if ($request->ajax()) {          
        return response()->json([
            'auth' => $auth,
            'intended' => URL::previous(),
            'errors' => $errors
        ]);
    }

    return redirect()->intended(URL::route('dashboard'));

}

我正在尝试通过url()->previous()获取上一个URL,但它返回登录页面的URL。请有人指导我如何解决这个问题。任何改进/帮助都将不胜感激。
我正在使用Laravel 5.4

我不知道我的方法是否正确,但我完全用不同的方式来做。我不使用ajax(),而是像在post中一样传递值,没有ajax并返回错误或重定向... - user8517929
使用back()函数并将其作为文本传递。 - user8517929
你的问题解决了吗? - Alihossein shahabi
使用会话来实现。每当登录中间件拒绝访问时,您可以将其放入会话中并赋予特定的键。每当用户成功登录并重定向到该路由时,请清除会话。 - Amin.Qarabaqi
8个回答

7
我这里有一个非常相似的问题:Laravel 5.6上的Ajax身份验证重定向。正如@aimme(https://stackoverflow.com/users/1409707/aimme)指出的那样,Ajax调用是无状态的,因此基本上您无法与后端进行交互。他和我建议的方法是将要重定向到的页面的URL传递给后端,或者在您的情况下,您可以通过post参数来实现,例如:
return response()->json([
    'auth' => false,
    'intended' => $request->intended,
    'errors' => $validator->errors()
]);

4

对于AJAX调用,不需要做任何特殊的处理。

在表单提交后,按照常规方式将重定向到后端。

return redirect()->route('dashboard');

在前端,你只需确保使用重定向的URL来更改window.location。这将导致浏览器刷新并转到新页面。

axios.post(url, formData).then(response => {
    window.location = response.request.responseURL;
});

这段代码片段是针对流行的Axios库的,但是同样的操作也可以用jQuery或纯JavaScript完成。

3
"可能会对你有帮助。"
"不要使用这些 return redirect()->intended(URL::route('dashboard'));,而是使用"
return redirect('dashboard');

我在谈论关于AJAX请求部分。 - Waleed
他需要根据他所在的位置动态地设置页面。 - Kerel

3

Laravel 5.4及以上版本支持,低版本不确定。

 return redirect()->back();

这将会从你来的上一页进行重定向。

Ajax 部分

 <script type="text/javascript">
    var url = "<?php echo url()->previous(); ?>";
    location.href = url;
 </script>

                OR simply javascript function
 history.go(-1);

请检查以上内容是否正常工作,对于您的代码进行检查。


2
如果我正确理解了您的问题,那么问题在于当您尝试在JSON响应中提供重定向URL时,您会混淆“先前”的URL和“预期”的URL。实际上,“先前”的URL是指HTTP Referrer,而不是预期的URL,后者是由Laravel的auth中间件设置在会话中的。
HTTP referrer是发起请求的页面。如果您当前在页面/foo上,并单击链接到页面/bar,则/bar上的HTTP Referrer将是/foo。当您发起AJAX请求时,发起请求的页面将成为您所访问终端点的引用页。在您的情况下,您的登录页面通过AJAX发起请求到您的登录处理程序。
当您尝试访问受Laravel auth中间件保护的页面时,此时Laravel会在将您重定向到登录页面之前,在会话中设置预期 URL的值。Laravel将预期 URL存储在会话中作为url.intended(您可以在Illuminate\Routing\Redirector::intended中看到这一点,这就是redirect()->intended()调用的内容)。因此,您只需要从会话中获取它即可。
if ($request->ajax()) {          
    return response()->json([
        'auth' => $auth,
        'intended' => session()->pull('url.intended') ?: URL::route('dashboard'),
        'errors' => $errors
    ]);
}

return redirect()->intended(URL::route('dashboard'));

注意: 使用->pull将在检索到项目后从会话中删除该项目。

更简单的方法是仅从预期的RedirectResponse中获取目标URL:

$redirect = redirect()->intended(URL::route('dashboard'))

if ($request->ajax()) {          
    return response()->json([
        'auth' => $auth,
        'intended' => $redirect->getTargetUrl(),
        'errors' => $errors
    ]);
}

return $redirect;

2

我通过在表单中添加一个包含url()->previous()值的隐藏字段来解决了这个问题,因为我没有其他方法获取前一页即页面A的URL。我尝试了几乎所有上面的答案。


1
URL::previous();

这个方法可以帮助你获取之前的URL,然后你可以使用jQuery将用户重定向到那里,类似于这样:

window.location.href = url; // <- you can try your url here.

祝你好运!!


他在帖子中表示URL::previous();对他不起作用。jQuery重定向代码可以工作,但在你的示例中未定义url。从这个答案中阅读不清楚他应该做什么。 - Kerel

1

首先,在后端收到请求时,请保存redirect()->intended()。

intended()会检查session索引url.intended是否存在,并默认重定向到该URL,否则将重定向到$default='/',可以被覆盖。

然后在请求成功时传递此URL,例如:

function testAjax(handleData) {
  $.ajax({
    url:"getvalue.php",  
    success:function(data) {
      window.location.href = data.url;
    }
  });
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接