如何在AJAX发布

时间:2016-02-15 22:08:57

标签: ajax laravel-5

我有一个网站,客人可以通过模式表格登录。 我提出的解决方案是工作,但我觉得这样做是一种肮脏/不安全的方式。 在主布局中,我加载包含模态窗体的局部视图。

当用户通过身份验证时,我刷新导航栏以显示登录的用户名。这是我感到困惑的部分。不可能刷新'导航栏也是局部视图。

登录-modal.blade.php

<div class="ui small modal" id="loginModal">
<div class="header">
    Login
</div>

<div class="ui active dimmer" id="loader" style="display: none">
    <div class="ui text loader">Loading</div>
</div>

<div class="content">
    <div class="ui grid">
        <div class="nine wide column centered">
            {!! Form::open(array('route' => 'auth.login', 'method' => 'post','id'=>'formLogin','class' => 'ui large form')) !!}
            <meta name="csrf_token" content="{{ csrf_token() }}"/>

            <div class="field {!! $errors->has('password') ? 'error' : '' !!}">
                <div class="ui left icon input">
                    <i class="user icon"></i>
                    {!! Form::text('username','',['name'=>'username','id'=>'username','class' => 'pd','placeholder'=>'Username']) !!}
                </div>
                {!! $errors->first('username', '<span class="ui text" id="" style="color: #bf4d4b">:message</span>') !!}
            </div>
            <div class="field {!! $errors->has('password') ? 'error' : '' !!}">
                <div class="ui left icon input">
                    <i class="lock icon"></i>
                    {!! Form::password('password',['name'=>'password','id'=>'password','class' => '','placeholder'=>'Password']) !!}
                </div>
                {!! $errors->first('password', '<span class="ui text" id="" style="color: #bf4d4b">:message</span>') !!}
            </div>
            {!! Form::submit('Login',['id'=>'loginButton','class'=>'ui fluid large teal submit button']) !!}

            <div class="ui error message"></div>

            {!! Form::close() !!}
            <div class="ui message">
                No account? <a href="#"> Sign Up</a>
            </div>
        </div>
    </div>
</div>
<div class="actions">
</div>
</div>

现在javascript在同一个文件中:

<script>
    $('#loginButton').click(function () {
        $('#loginModal').modal(
                {
                    blurring: true,
                    closable: true,
                })
                .modal('show');
    });

    $(document).ready(function () {
        $('form#formLogin').submit(function (e) {
            e.preventDefault();
            $.ajax({
                type: 'post',
                timeout: 10000,
                url: $('form#formLogin').attr('action'),
                dataType: 'json',
                data: $('form#formLogin').serialize(),
                beforeSend: function (xhr) {
                    $('div#loader').show();
                    var token = $('meta[name="csrf_token"]').attr('content');

                    if (token) {
                        return xhr.setRequestHeader('X-CSRF-TOKEN', token);
                    }
                },
                complete: function () {
                    $('div#loader').hide();
                },
                success: function (data) {
                    if (data.success == false) {
                       var errors = data.errors;                                            $('#loginModal').find('div.field.error').removeClass("field error").addClass("field");
                        $('#loginModal').find('span').remove();
                        $.each(errors, function (field, errormsg) {

                            if (errormsg.length != 0) {

                                var currentField = $('#loginModal').find('#' + field);
                                var currentFieldSpan = $('#loginModal').find('#span' + field);

                                if (currentFieldSpan.length > 0) {
                                    $('#loginModal').find('div.field.error').removeClass("field error").addClass("field");
                                    $('#loginModal').find('span').remove();

                                }
                                currentField.closest("div.field").removeClass("field").addClass("field error");
                                $("<span class='ui text' id='span" + field + "' style='color: #bf4d4b'>" + errormsg + "</span>").insertAfter(currentField.closest("div.ui.left.icon.input"));
                            }
                        });
                        if ((typeof data.locked != 'undefined') && data.locked.status == true) {
                            //BIDOUILLE pour disable le button login//

                            function enableLoginButton() {
                                $('#loginModal').find('#loginButton').removeClass('disabled');
                            }

                            //disable login button
                            $('#loginModal').find('#loginButton').addClass('disabled');
                            //after lockout time enable the login button again
                            setTimeout(enableLoginButton, (data.locked.remainingtime * 1000));

                        }
                    }
                    else if (data.success == true) {//authentication was successful

                        var cnt = '<div class="ui simple dropdown item">' +
                                '<img class="logo" src="{{ asset('images/food.png') }}" style="margin-right: 1em">' +
                                data.user['username'] +
                                ' <i class="dropdown icon"></i>' +
                                '<div class="menu">' +
                                '<a class="item" href="#">Link Item</a>' +
                                '<a class="item" href="#">Link Item</a>' +
                                '<div class="divider"></div>' +
                                '<div class="header">Header Item</div>' +
                                '<div class="item">' +
                                '<i class="dropdown icon"></i>' +
                                'Sub Menu' +
                                '<div class="menu">' +
                                '<a class="item" href="#">Link Item</a>' +
                                '<a class="item" href="#">Link Item</a>' +
                                '</div>' +
                                '</div>' +
                                '<a class="item" href="#">Link Item</a>' +
                                '</div>' +
                                '</div>'

                        //remove the signin button
                        $('#navbartop .right .item').remove();
                        //add the dropdown with username
                        $('#navbartop .right').append(cnt);
                        //dissmis modal
                        $('#loginModal').modal().modal('hide');
                    }
                },
                error: function (xhr) {

                    var validationerrors = xhr.responseJSON;
                    $('#loginModal').find('div.field.error').removeClass("field error").addClass("field");
                    $('#loginModal').find('span').remove();
                    $.each(validationerrors, function (field, errormsg) {

                        if (errormsg.length != 0) {

                            //select the field
                            var currentField = $('#loginModal').find('#' + field);
                            var currentFieldSpan = $('#loginModal').find('#span' + field);

                            if (currentFieldSpan.length > 0) {
                                $('#loginModal').find('div.field.error').removeClass("field error").addClass("field");
                                $('#loginModal').find('span').remove();

                            }
                            //apply 'field error' class to the closest div with 'field' class
                            currentField.closest("div.field").removeClass("field").addClass("field error");

                            //appends a span with red text and the validation error message
                            $("<span class='ui text' id='span" + field + "' style='color: #bf4d4b'>" + errormsg + "</span>").insertAfter(currentField.closest("div.ui.left.icon.input"));
                        }
                    });
                }
            });
            return false;
        });
    });
</script>

AuthController.php:

protected function handleUserWasAuthenticated(Request $request, $throttles)
    {

        if ($throttles) {
            $this->clearLoginAttempts($request);
        }

        if (method_exists($this, 'authenticated')) {
            return $this->authenticated($request, Auth::guard($this->getGuard())->user());
        }

        //if user intended to access Logout() while not logged in, avoid instant redirect and logout
        if (str_contains(redirect()->intended()->getTargetUrl(),'auth/logout')) {
            return redirect()->route('home.index')->with('success', Auth::user()->username.' logged in successfully. ');
        }
        if($request->ajax())
        {
            return Response::json(['success' => true, 'errors' => '','user'=> Auth::user()]);
        }
        return redirect()->intended($this->redirectPath())->with('success', Auth::user()->username.' logged in successfully. ');
    }
    public function login(Request $request)
    {


        $this->validateLogin($request);

        // If the class is using the ThrottlesLogins trait, we can automatically throttle
        // the login attempts for this application. We'll key this by the username and
        // the IP address of the client making these requests into this application.
        $throttles = $this->isUsingThrottlesLoginsTrait();

        if ($throttles && $lockedOut = $this->hasTooManyLoginAttempts($request)) {
            $this->fireLockoutEvent($request);

            return $this->sendLockoutResponse($request);
        }

        $credentials = $this->getCredentials($request);

        if (Auth::guard($this->getGuard())->attempt($credentials, $request->has('remember'))) {
            return $this->handleUserWasAuthenticated($request, $throttles);
        }

        // If the login attempt was unsuccessful we will increment the number of attempts
        // to login and redirect the user back to the login form. Of course, when this
        // user surpasses their maximum number of attempts they will get locked out.
        if ($throttles && ! $lockedOut) {
            $this->incrementLoginAttempts($request);
        }
        if($request->ajax())
        {
            return Response::json(['success' => false, 'errors' =>
                [$this->loginUsername() => $this->getFailedLoginMessage()]
            ]);
        }
        return $this->sendFailedLoginResponse($request);


    }
    protected function sendLockoutResponse(Request $request)
    {
        $seconds = app(RateLimiter::class)->availableIn(
            $this->getThrottleKey($request)
        );

        if($request->ajax()) {

                return Response::json(['success' => false,
                    'errors' =>
                        [$this->loginUsername() => $this->getLockoutErrorMessage($seconds)],
                    'locked' =>
                        ['status'=>true, 'remainingtime'=>$seconds]]);

        }

        return redirect()->back()
            ->withInput($request->only($this->loginUsername(), 'remember'))
            ->withErrors([
                $this->loginUsername() => $this->getLockoutErrorMessage($seconds),
            ]);
    }

2 个答案:

答案 0 :(得分:0)

我想你需要改变这一行:

'<img class="logo" src="{{ asset('images/food.png') }}" style="margin-right: 1em">'

有关

'<img class="logo" src="{{ asset(\'images/food.png\') }}" style="margin-right: 1em">'

我希望它有效;)

答案 1 :(得分:0)

我会将导航栏包装成这样的div:

<div id="ajax-nav">
<!-- Nav here -->
</div>

然后,当您的登录响应成功时,您可以重新加载导航栏:

$('#ajax-nav').load("some url that returns the html of the navbar");

然后你只需要一条通向Controller的路线,该路由器可以根据用户登录状态(登录或访客)生成导航栏。

通过此过程,您可以在成功登录等特定事件后用新生成的导航栏完全替换导航栏的内容,或者甚至可以设置刷新导航栏的间隔 - 但在您的情况下不应该需要