代码之家  ›  专栏  ›  技术社区  ›  Ivar

ajax请求后的Laravel重定向。(不允许使用方法)

  •  1
  • Ivar  · 技术社区  · 1 年前

    我有一个奇怪的问题。我在Vue 3中有一个带有Inertia的web应用程序,其中包含表单。当我打开两个浏览器并在其中一个中注销,然后在另一个中触发Ajax请求时,它就会到达中间件。这是我所期望的,但使用我所写的中间件:

    namespace App\Http\Middleware;
    
    use Closure;
    use Illuminate\Http\Request;
    use Symfony\Component\HttpFoundation\Response;
    
    class ProtectAjaxCalls
    {
        /**
         * Handle an incoming request.
         *
         * @param \Closure(\Illuminate\Http\Request): (\Symfony\Component\HttpFoundation\Response) $next
         */
        public function handle(Request $request, Closure $next): Response
        {
            if ($request->ajax() && !auth()->user()) {
                return redirect()->route('login');
                // dd($request);
            }
    
            return $next($request);
        }
    }
    

    它重定向到登录页面。同样,这也是我所期望的。我不明白的是,如果Ajax调用是一个补丁请求,那么重定向也会变成一个补丁申请,当然会失败。这里发生了什么,我如何正确地将无效的补丁请求重定向到登录页面的有效get请求?

    我可以使用的一个解决方案是返回403,然后执行:

    window.location.href = "/login"
    

    这是要走的路吗?

    2 回复  |  直到 1 年前
        1
  •  0
  •   Ivar    1 年前

    我的案子我必须做:

    namespace App\Http\Middleware;
    
    use Closure;
    use Illuminate\Http\Request;
    use Inertia\Inertia;
    use Symfony\Component\HttpFoundation\Response;
    
    class ProtectAjaxCalls
    {
        /**
         * Handle an incoming request.
         *
         * @param \Closure(\Illuminate\Http\Request): (\Symfony\Component\HttpFoundation\Response) $next
         */
        public function handle(Request $request, Closure $next): Response
        {
            if ($request->ajax() && !auth()->user()) {
                return Inertia::location('/login');
            }
    
            return $next($request);
        }
    }
    

    在我的视图中为我节省了很多代码

        2
  •  -6
  •   Oybek Odilov    1 年前

    女贞子,伊瓦尔!您遇到的问题是由于HTTP重定向的性质造成的。当服务器以重定向状态进行响应时,客户端应该对新URL发出相同类型的请求(GET、POST、PATCH等)。这就是为什么您的PATCH请求被重定向为PATCH请求,而这不是您想要的。

    要解决此问题,可以使用基于JavaScript的解决方案在客户端处理重定向。您可以返回一个JSON响应,其中包含要重定向到的URL,而不是从中间件返回重定向响应。然后,在JavaScript代码中,您可以检查此响应并使用 window.location.href .

    以下是如何修改中间件:

    namespace App\Http\Middleware;
    
    use Closure;
    use Illuminate\Http\Request;
    use Symfony\Component\HttpFoundation\Response;
    
    class ProtectAjaxCalls
    {
        /**
         * Handle an incoming request.
         *
         * @param \Closure(\Illuminate\Http\Request): (\Symfony\Component\HttpFoundation\Response) $next
         */
        public function handle(Request $request, Closure $next): Response
        {
            if ($request->ajax() && !auth()->user()) {
                return response()->json(['redirect' => route('login')], 401);
            }
    
            return $next($request);
        }
    }
    

    在您的JavaScript代码中,您可以这样处理重定向:

    axios.patch('/your-endpoint')
        .then(response => {
            // Handle successful response
        })
        .catch(error => {
            if (error.response.status === 401 && error.response.data.redirect) {
                window.location.href = error.response.data.redirect;
            }
        });
    

    这样,无论原始请求类型如何,重定向都将始终是GET请求。