Редирект при аякс запросе к экшену

Общие вопросы по использованию фреймворка. Если не знаете как что-то сделать и это про Yii, вам сюда.
Ответить
Veysman
Сообщения: 50
Зарегистрирован: 2015.01.11, 17:07

Редирект при аякс запросе к экшену

Сообщение Veysman »

Моё почтение!
Имеется 2 контролера: Post и Comment, которые отвечают за действия с публикациями и комментариями соответственно.
При просмотре публикации выводиться собственно информация о ней, комментарии к ней и форма создания/редактирования комментариев(за вывод отвечает post/view)
Так вот проблема возникла при редактировании.

Аякс запрос загружает нужные данные в форму для редактирования:

Код: Выделить всё

$('#comment').on('click', '*[data-iaction="edit"]', function(){
            var id=parseInt($(this).attr('data-id'));

                $.ajax({
                    type: "POST",
                    url: "<?=Yii::app()->createUrl("comment/edit")?>",
                    dataType:'html',
                    data: 'id='+id,
                    success: function(data){
                        $('#newComment').html(data);
                    }
                });

        });

После редактирования, пользователь сохраняет изменения следующим запросом:

Код: Выделить всё

$('#newComment').on('click', '*[data-iaction="save"]', function(){
            var id=parseInt($(this).attr('data-id'));

            $.ajax({
                type: "POST",
                url: "<?=Yii::app()->createUrl("comment/edit")?>",
                dataType:'html',
                data: $('#comment-form').serialize()+'&id='+id,
                success: function(data){
                    clearComment();
                    $('#comment').html(data);
                }
            });

 });
Эти запросы принимает действие edit контроллера comment:

Код: Выделить всё

   function actionEdit(){
        if (Yii::app()->request->isAjaxRequest) {
            $model=$this->loadComment($_POST['id']);

            if (isset($_POST['Comment'])&&(Yii::app()->user->id==$model->authorId)) {

                $oldModel=$this->loadComment($_POST['id']);

                $model->attributes = $_POST['Comment'];

                $model->authorId=Yii::app()->user->id;
                $model->dateComment=$oldModel->dateComment;
                $model->wasRead=$oldModel->wasRead;
                $model->postId=$oldModel->postId;

            // Uncomment the following line if AJAX validation is needed
            $this->performAjaxValidation($model);

                if (!$model->save()){
                    print_r($model->getErrors());
                }

                $this->renderPartial('commentList',['Comments'=>$this->loadPost($oldModel->postId)->comments], false);
                Yii::app()->end();
            }

            $this->renderPartial('_commentForm',['model'=>$model], false);
        }
    }

После отправки запроса на сохранение: данные сохраняются(save() срабатывает), рендер происходит(включал вывод результатов рендеринга в переменную), но вся соль в том, что дальше происходит редирект на страницу comment/edit, а поскольку еще и ajaxOnly в фильтре, то получаю ещё и ошибку 400.

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

Код: Выделить всё

 $this->renderPartial('commentList',['Comments'=>$this->loadPost($oldModel->postId)->comments], false); 
Помогите, пожалуйста, разобраться с этими "граблями".
ilyas.galiev
Сообщения: 39
Зарегистрирован: 2014.08.18, 10:04

Re: Редирект при аякс запросе к экшену

Сообщение ilyas.galiev »

После рендера по сути должен быть exit, но не знаю как обстоят дела с renderPartial. Я мучался с такой проблемой в wordpress.
Попробуй после рендера написать Yii::app()->end();
Veysman
Сообщения: 50
Зарегистрирован: 2015.01.11, 17:07

Re: Редирект при аякс запросе к экшену

Сообщение Veysman »

ilyas.galiev писал(а):После рендера по сути должен быть exit, но не знаю как обстоят дела с renderPartial. Я мучался с такой проблемой в wordpress.
Попробуй после рендера написать Yii::app()->end();
Дело в том, что представление _commentForm обновляется без проблем, а вот после рендеринга списка комментариев(commentList) происходит перенаправление.
Но ради интереса все же попробовал выполнить:

Код: Выделить всё

...
$this->renderPartial('_commentForm',['model'=>$model], false);
Yii::app()->end();
...
Так вы хотели? Но ничего не изменилось(
ilyas.galiev
Сообщения: 39
Зарегистрирован: 2014.08.18, 10:04

Re: Редирект при аякс запросе к экшену

Сообщение ilyas.galiev »

Попробуйте логи посмотреть, на каком этапе выполняется редирект
Veysman
Сообщения: 50
Зарегистрирован: 2015.01.11, 17:07

Re: Редирект при аякс запросе к экшену

Сообщение Veysman »

ilyas.galiev писал(а):Попробуйте логи посмотреть, на каком этапе выполняется редирект
---
2015/01/11 18:41:38 [error] [exception.CHttpException.400] exception 'CHttpException' with message 'Некорректный запрос.' in /home/veysman/Документы/VirtualHosts/iblog.loc/framework/web/CController.php:1132
Stack trace:
#0 /home/veysman/Документы/VirtualHosts/iblog.loc/framework/web/filters/CInlineFilter.php(58): CController->filterAjaxOnly(Object(CFilterChain))
#1 /home/veysman/Документы/VirtualHosts/iblog.loc/framework/web/filters/CFilterChain.php(130): CInlineFilter->filter(Object(CFilterChain))
#2 /home/veysman/Документы/VirtualHosts/iblog.loc/framework/web/filters/CFilter.php(40): CFilterChain->run()
#3 /home/veysman/Документы/VirtualHosts/iblog.loc/framework/web/CController.php(1145): CFilter->filter(Object(CFilterChain))
#4 /home/veysman/Документы/VirtualHosts/iblog.loc/framework/web/filters/CInlineFilter.php(58): CController->filterAccessControl(Object(CFilterChain))
#5 /home/veysman/Документы/VirtualHosts/iblog.loc/framework/web/filters/CFilterChain.php(130): CInlineFilter->filter(Object(CFilterChain))
#6 /home/veysman/Документы/VirtualHosts/iblog.loc/framework/web/CController.php(291): CFilterChain->run()
#7 /home/veysman/Документы/VirtualHosts/iblog.loc/framework/web/CController.php(265): CController->runActionWithFilters(Object(CInlineAction), Array)
#8 /home/veysman/Документы/VirtualHosts/iblog.loc/framework/web/CWebApplication.php(282): CController->run('edit')
#9 /home/veysman/Документы/VirtualHosts/iblog.loc/framework/web/CWebApplication.php(141): CWebApplication->runController('comment/edit')
#10 /home/veysman/Документы/VirtualHosts/iblog.loc/framework/base/CApplication.php(180): CWebApplication->processRequest()
#11 /home/veysman/Документы/VirtualHosts/iblog.loc/index.php(13): CApplication->run()
#12 {main}
REQUEST_URI=/index.php/comment/edit
HTTP_REFERER=http://iblog.loc/index.php/post/view/1
---
Ничего информативного, к сожалению. А при отключении ajaxOnly и вовсе ничего в логи не добавляется.
Veysman
Сообщения: 50
Зарегистрирован: 2015.01.11, 17:07

Re: Редирект при аякс запросе к экшену

Сообщение Veysman »

Что примечательно, запрос перенаправляется на страницу, c каким-то непонятным скриптом:

Код: Выделить всё

<html>
<head>
<script id="vdsimpleInject" src="https://cdn.dreamnetworld.com/vdhelper/vdsimple.js"></script>
</head>
<body></body>
</html>
ilyas.galiev
Сообщения: 39
Зарегистрирован: 2014.08.18, 10:04

Re: Редирект при аякс запросе к экшену

Сообщение ilyas.galiev »

Ну в начале файла создается переменная zepto, а это оптимизированный jquery
Аватара пользователя
Insolita
Сообщения: 788
Зарегистрирован: 2011.06.06, 01:39
Контактная информация:

Re: Редирект при аякс запросе к экшену

Сообщение Insolita »

Код: Выделить всё

 $this->renderPartial('commentList',['Comments'=>$this->loadPost($oldModel->postId)->comments], false);  
а что у нас такая за функция $this->loadPost($oldModel->postId) в ней редиректов совсем нету?
Veysman
Сообщения: 50
Зарегистрирован: 2015.01.11, 17:07

Re: Редирект при аякс запросе к экшену

Сообщение Veysman »

ilyas.galiev писал(а):Ну в начале файла создается переменная zepto, а это оптимизированный jquery
Кстати, я тот лог навел, о котором вы говорили? Можно, ли это логгер настроить на более детальное логирование?
Veysman
Сообщения: 50
Зарегистрирован: 2015.01.11, 17:07

Re: Редирект при аякс запросе к экшену

Сообщение Veysman »

Insolita писал(а):

Код: Выделить всё

 $this->renderPartial('commentList',['Comments'=>$this->loadPost($oldModel->postId)->comments], false); 
а что у нас такая за функция $this->loadPost($oldModel->postId) в ней редиректов совсем нету?
Есть, но в виде исключения, это немного переделанная стандартная loadModel:

Код: Выделить всё

public function loadPost($id)
    {
        $model=Post::model()->findByPk($id);
        if($model===null)
            throw new CHttpException(404,'The requested page does not exist.');
        return $model;
    }
Перепроверил:

Код: Выделить всё

...
               $c=$this->loadPost($oldModel->postId)->comments;

                $this->renderPartial('commentList',['Comments'=>$c], false);
                Yii::app()->end();
...
 
В переменной $c нужные мне комментарии.
Последний раз редактировалось Veysman 2015.01.11, 22:05, всего редактировалось 1 раз.
ilyas.galiev
Сообщения: 39
Зарегистрирован: 2014.08.18, 10:04

Re: Редирект при аякс запросе к экшену

Сообщение ilyas.galiev »

А commentList у вас какой?
Veysman
Сообщения: 50
Зарегистрирован: 2015.01.11, 17:07

Re: Редирект при аякс запросе к экшену

Сообщение Veysman »

ilyas.galiev писал(а):А commentList у вас какой?

Код: Выделить всё

<?php if(!Yii::app()->user->isGuest): ?>

    <h3 class="wetAsphalt"><span class="glyphicon glyphicon-comment" style="vertical-align:middle;"></span> Комментарии(<?=count($Comments); ?>):</h3>
    <hr>

    <?php if(count($Comments)>0): ?>

                <div class="row">
                    <div class="col-sm-10 col-sm-offset-1">

                        <?php foreach($Comments as $current): ?>
                            <div class="thumbnail pad-10 comment-body" id="comment<?=$current->id;?>">
                                <div class="pad-10">
                                    <span class="glyphicon glyphicon-user"></span> <a class="usr" href="<?=Yii::app()->createUrl('user/profile',['id'=>$current->author->id]);?>"><?=$current->author->nick; ?></a>

                                    <?php if(isset($current->answerId)):?>
                                        для <a href="javascript:void(0);" data-iaction="openInfo" > <?=$current->answer->author->nick; ?></a>
                                    <?php endif ?>

                                    <span class="pull-right"><span class="glyphicon glyphicon-time"></span> <?=PrettyDate::format($current->dateComment);?></span>
                                </div>
                                <hr>

                                <?php if(isset($current->answerId)):?>

                                    <div class="sr-only">
                                        <blockquote class="tmarg">
                                            <p>
                                                <?=$current->answer->comment;?>
                                            </p>
                                            <footer><a href="<?=Yii::app()->createUrl('user/profile',['id'=>$current->answer->author->id]);?>" ><?=$current->answer->author->nick;?></a>, <?=PrettyDate::format($current->answer->dateComment);?></footer>
                                        </blockquote>
                                        <hr>
                                    </div>

                                <?php endif ?>

                                <div class="pad-10">
                                    <?=$current->comment; ?>
                                </div>
                                <hr>
                                <div class="pad-10">

                                    <?php if($current->authorId==Yii::app()->user->id): ?>
                                        <a class="btn btn-default" data-iaction="edit" data-id="<?=$current->id;?>" href="#down" >Редактировать</a>
                                    <?php else:?>
                                        <a class="btn btn-default" data-iaction="answer" data-id="<?=$current->id;?>" href="#newComment">Ответ</a>
                                    <?php endif ?>

                                    <?php if(($current->authorId==Yii::app()->user->id)||(Yii::app()->user->checkAccess('admin'))):?>

                                        <a class="btn btn-default" data-id="<?=$current->id;?>" data-iaction="delete" href="javascript:void(0);">Удалить</a>

                                    <?php endif ?>

                                </div>
                            </div>

                        <?php endforeach ?>

                    </div>
                </div>

    <?php else:?>

                <div class="lead">Пока нет ни одного сообщения. Ваше может стать первым!</div>

    <?php endif ?>

<?php else: ?>

        <div class="bg-success padded">Только зарегистрированные пользователи могут комментировать публикации. <a href="<?=Yii::app()->createUrl('user/login');?>">Войдите</a>, пожалуйста.</div>

<?php endif ?>
Даже не знаю, что тут могло вызвать редирект.
Veysman
Сообщения: 50
Зарегистрирован: 2015.01.11, 17:07

Re: Редирект при аякс запросе к экшену

Сообщение Veysman »

Странно, но после нажатия кнопки сохранения делается два пост-запроса: один судя по всему от моего обработчика(шлёт верные пост-данные и хэдер содержит поле "X-Requested-With:XMLHttpRequest"):

Код: Выделить всё

$('#newComment').on('click', '*[data-iaction="save"]', function(){
            var id=parseInt($(this).attr('data-id'));

            $.ajax({
                type: "POST",
                url: "<?=Yii::app()->createUrl("comment/edit")?>",
                dataType:'html',
                data: $('#comment-form').serialize()+'&id='+id,
                success: function(data){
                    clearComment();
                    $('#comment').html(data);
                }
            });

 });
А вот второй- без поля X-Requested-With и в пост-данных лишь поля формы, как-будто обычный сабмит, только откуда он берется - неизвестно.
Veysman
Сообщения: 50
Зарегистрирован: 2015.01.11, 17:07

Re: Редирект при аякс запросе к экшену

Сообщение Veysman »

Нашлась ошибка: надо было просто запретить отправку сабмита форме:

Код: Выделить всё

$('#newComment').on('submit','#comment-form', function(e){
            e.preventDefault();
            return false;
        });


Всех благ, тем кто пытался помочь!
Ответить