Как исправить модальную форму AJAX в Laravel 5.3 - PullRequest
0 голосов
/ 19 апреля 2019

Я обновил свое приложение с Laravel 4.2 до Laravel 5.3. На странице указателя с цитатами у меня есть модальная форма AJAX для редактирования или просмотра учетных данных для ссылки. Это работало нормально в Laravel 4.2, но я не могу заставить его работать в 5.3. Примерно после 5 часов поиска в Google и пробуя разные вещи, я решил опубликовать это здесь, чтобы кто-то более опытный, чем я, мог указать мне правильное направление.

Вот ссылка на страницу индекса:

<a style="cursor: pointer; " title= "Login Credentials" data-loopback="cit-pg-1" data-citationid="1079" class="getCitationdetails"><span class="glyphicon glyphicon-lock " title="Login Credentials"></span></a>

А вот и JavaScript:

<script type="text/javascript">
$(document).on('click','.getCitationdetails',function(){
    var citationid = $(this).data('citationid');
    var loopback = $(this).data('loopback');
    $.ajax({
        url : '/citation-password',
        type:'post',
        data : {citationid :citationid, loopback :loopback},
        success:function(resp){
            $('#AppendLoginDetails').html(resp);
            $('#LoginCredentialsModal').modal('show');
            $('.loadingDiv').hide();
        },
        error:function(){
            alert('Error');
        }
    })
})

Вот мой маршрут:

    Route::match(['get', 'post'], '/citation-password', 'CitationsController@citationpassword');

А вот метод Controller, который генерирует форму при получении и сохраняет данные в записи:

    public function citationpassword()
{
    if (Request::ajax()) {
        $data = Request::all();
        if (!$data['citationid']) {
            return redirect('/citations')
                ->with('flash-danger', 'Missing citation id for Login credentials form!!');
        }
        // Save loopback variable if we have it in order to return user to the page where they came from; default return location is citations
        $loopback = 'citations';
        if (array_key_exists("loopback", $data)) {
            $loopback = $data['loopback'];
        }

        $getcitationdetails = Citation::where('id', $data['citationid'])->select('id', 'site_id', 'username', 'password', 'login_email', 'login_notes')->first();
        $getcitationdetails = json_decode(json_encode($getcitationdetails), true);
        $getsitedetails = Site::where('id', $getcitationdetails['site_id'])->select(
            'id',
            'directory_username',
            'directory_password',
            'security_questions',
            'email_account',
            'email_account_password',
            'email_account_name',
            'google_user',
            'google_pwd',
            'name_of_google_account'
        )->first();
        $getsitedetails = json_decode(json_encode($getsitedetails), true);
        $response ="";
        $response .= '<form action="'.url('/citation-password').'" method="post">
                        <div class="modal-body">';
        if (!empty($getsitedetails['directory_username'])) {
            $response .= '<div class="form-group">
                                <label for="recipient-name" class="col-form-label">Default login credentials for this site:</label>
                                <p>Username: '.$getsitedetails['directory_username'].'
                                <br />Password: '.$getsitedetails['directory_password'].'
                                <br />Email account: '.$getsitedetails['email_account'].'
                                <br />Email password: '.$getsitedetails['email_account_password'].'
                                <br />Name on email account: '.$getsitedetails['email_account_name'].'
                                <br />Default security questions: '.$getsitedetails['security_questions'].'</p>
                                <p>Gmail account: '.$getsitedetails['google_user'].'
                                <br />Gmail password: '.$getsitedetails['google_pwd'].'
                                <br />Name on Gmail account: '.$getsitedetails['name_of_google_account'].'</p>
                            </div>';
        }
                    $response .= '
                        <input type="hidden" name="_token" value="'.csrf_token() .'" />
                        <input type="hidden" name="citation_id" value="'.$data['citationid'].'" />
                        <input type="hidden" name="loopback" value="'.$loopback.'" />
                        <div class="form-group">
                            <label for="recipient-name" class="col-form-label">Username:</label>
                            <input type="text" class="form-control" name="username" value="'.$getcitationdetails['username'].'" autocomplete="off">
                        </div>
                        <div class="form-group">
                            <label for="message-text" class="col-form-label">Password:</label>
                            <input type="text" class="form-control" name="password" value="'.$getcitationdetails['password'].'" autocomplete="off">
                        </div>
                        <div class="form-group">
                            <label for="message-text" class="col-form-label">Login email used:</label>
                            <input type="text" class="form-control" name="login_email" value="'.$getcitationdetails['login_email'].'" autocomplete="off">
                        </div>
                        <div class="form-group">
                            <label for="message-text" class="col-form-label">Login notes:</label>
                            <textarea class="form-control" style="height:130px;" name="login_notes">'.$getcitationdetails['login_notes'].'</textarea>
                        </div>

                </div>
                <div class="modal-footer">
                <button type="submit" class="btn btn-success" id="success">Save</button>
                <button type="button" class="btn btn-danger" data-dismiss="modal" aria-hidden="true">Cancel</button>
                </div>
                </form>';
                return $response;
    } else {
        // The popup modal has posted back here; process the data
        $data = Request::all();
        // Handle & translate loopback; returning user to the page where they came from
        $loopback = 'citations';
        if ($data['loopback']) {
            $loopback = $data['loopback'];
            // Translate pages it came from
            $trackLoopback = new trackLoopback();
            $loopback = $trackLoopback->translate($loopback);
        }
        $updatecitation = Citation::find($data['citation_id']);
        $updatecitation->username = $data['username'];
        $updatecitation->password = $data['password'];
        $updatecitation->save();
        return redirect($loopback)
            ->with('flash-success', 'Login credentials have been updated successfully!');
    }
}

Чтобы выделить ошибку, я даже упростил форму в контроллере следующим образом:

    public function citationpassword()
{
    if (Request::ajax()) {
        return '<p>This is the modal form!</p>';

    } else {
        // The popup modal has posted back here; process the data
        $data = Request::all();
        // Handle & translate loopback; returning user to the page where they came from
        $loopback = 'citations';
        if ($data['loopback']) {
            $loopback = $data['loopback'];
            // Translate pages it came from
            $trackLoopback = new trackLoopback();
            $loopback = $trackLoopback->translate($loopback);
        }
        $updatecitation = Citation::find($data['citation_id']);
        $updatecitation->username = $data['username'];
        $updatecitation->password = $data['password'];
        $updatecitation->save();
        return redirect($loopback)
            ->with('flash-success', 'Login credentials have been updated successfully!');
    }
}

, а также упростили маршрут до этого:

    Route::get('/citation-password', 'CitationsController@citationpassword');

но все, что я получаю, нажимая на ссылку, - это всплывающее уведомление «Ошибка».

У меня нет опыта работы с AJAX. Как получить форму для отображения в Laravel 5.3?

И / или, как я могу изменить функцию JavaScript, чтобы она отображала фактическую ошибку вместо уведомления «Ошибка»? (Я попробовал несколько методов, которые я нашел в StackOverflow, чтобы отобразить ошибки, но все они не привели к уведомлению об ошибках; просто пустая страница. И мне не удалось заставить мой отладчик Firefox отображать ошибки.)

Спасибо!

1 Ответ

0 голосов
/ 23 апреля 2019

Правильный способ отладки JavaScript - это публиковать ошибки следующим образом:

<script type="text/javascript">
$(document).on('click','.getCitationdetails',function(){
    var citationid = $(this).data('citationid');
    var loopback = $(this).data('loopback');
    $.ajax({
        url : '/citation-password',
        type:'post',
        data : {citationid :citationid, loopback :loopback},
        success:function(resp){
            $('#AppendLoginDetails').html(resp);
            $('#LoginCredentialsModal').modal('show');
            $('.loadingDiv').hide();
        },
        error: function(xhr, ajaxOptions, thrownError) {
             alert(thrownError + "\r\n" + xhr.statusText + "\r\n" + xhr.responseText);
        }

    })
})

Как только вы это сделаете, вы увидите, что ошибка связана с отсутствующим CsrfToken для формы.[Фактическое сообщение об ошибке из структуры Laravel: Illuminate \ Session \ TokenMismatchException: в файле /home/reviewsites/moxy53/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/VerifyCsrfToken.php on line 6 Since)и глаголы get и post используют один и тот же маршрут, Laravel требует CsrfToken до того, как сформируется форма с полем Csrf.

Можно (но НЕ рекомендуется!) Исключить этот маршрут из защиты CSRF, отредактировав App \ Http \ Middleware \ VerifyCsrfToken.php со следующим исключением:

    /**
 * The URIs that should be excluded from CSRF verification.
 *
 * @var array
 */
protected $except = [
    '/citation-password',
];  

Однако гораздо лучший подход - добавить токен.Правильно, что, поскольку вы используете метод post для отправки значений данных в контроллер, вы не можете использовать контроллер для генерации поля токена в форме.Следовательно, решение состоит в том, чтобы извлечь html из контроллера и поместить его в блейд.Эти строки:

$response .= '<form action="'.url('/citation-password').'" method="post">
    <div class="modal-body">';

        ...
    </div>
</form>';

не должны находиться в ответе $, генерируемом контроллером, а должны находиться в модальном div в самом блейде. ТО , вы можете добавить поле CSRF в блейд следующим образом:

<form action="{{url('/citation-password')}}" method="post">
    {{ csrf_field() }}
    <div class="modal-body" id="AppendLoginDetails">
    </div>
</form>
...