ajax некоректно работает

Общие вопросы по использованию второй версии фреймворка. Если не знаете как что-то сделать и это про Yii 2, вам сюда.
Ответить
vano.mig
Сообщения: 73
Зарегистрирован: 2016.11.21, 10:25

ajax некоректно работает

Сообщение vano.mig »

Всем привет. Помогите найти ошибку.
Пытаюсь передать форму аяксом и сохранить ее в базу. После сохранение данных в базе получаю статус ок и ошибку
yii\web\HeadersAlreadySentException: Headers already sent in
frontend/controllers/SiteController.php on line 270
вот контроллер, нужен action Support

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

<?php
namespace frontend\controllers;

use frontend\models\GalleryLang;
use Yii;
use yii\base\InvalidParamException;
use yii\web\BadRequestHttpException;
use yii\filters\VerbFilter;
use yii\filters\AccessControl;
use frontend\models\LoginForm;
use frontend\models\PasswordResetRequestForm;
use frontend\models\ResetPasswordForm;
use frontend\models\SignupForm;
use frontend\models\ContactForm;
use frontend\models\News;
use frontend\models\Support;
use frontend\models\EventsDay;
use frontend\modules\admin\models\googleAuth\GoogleAuthenticator;

/**
 * Site controller
 */
class SiteController extends HeadController
{
    /**
     * {@inheritdoc}
     */
    public function behaviors()
    {
        return [
            'access' => [
                'class' => AccessControl::className(),
                'only' => ['logout', 'signup'],
                'rules' => [
                    [
                        'actions' => ['signup'],
                        'allow' => true,
                        'roles' => ['?'],
                    ],
                    [
                        'actions' => ['logout'],
                        'allow' => true,
                        'roles' => ['@'],
                    ],
                ],
            ],
            'verbs' => [
                'class' => VerbFilter::className(),
                'actions' => [
                    'logout' => ['post'],
                ],
            ],
        ];
    }

    /**
     * {@inheritdoc}
     */
    public function actions()
    {
        return [
            'error' => [
                'class' => 'yii\web\ErrorAction',
            ],
            'captcha' => [
                'class' => 'yii\captcha\CaptchaAction',
                'fixedVerifyCode' => YII_ENV_TEST ? 'testme' : null,
            ],
        ];
    }

    /**
     * Displays homepage.
     * @return mixed
     */
    public function actionIndex()
    {
        $this->setMetaData(Yii::t('site', 'FSLU'), Yii::t('head', 'MainDesc'), Yii::t('head', 'MainCont'));
        $sidebar = News::find()->asArray()->with('newsLang')->where(['status'=>News::STATUS_ACTIVE])->orderBy(['id'=>SORT_DESC])->limit(4)->all();
        $sidebar_main = '';
        if($sidebar)
        {
            $sidebar_main = array_shift($sidebar);
        }
        $support = new Support();
        $gallery = GalleryLang::find()->with(['gallery'])->where(['lang'=>Yii::$app->language])->orderBy(['id'=>SORT_DESC])->limit(6)->all();
        $events = \common\models\EventsDay::find()->where(['lang'=>Yii::$app->language])->all();
        return $this->render('index', ['sidebar'=>$sidebar, 'main'=>$sidebar_main, 'support'=>$support, 'gallery'=>$gallery, 'events'=>$events]);

    }

    /**
     * Logs in a user.
     * @return mixed
     */
    public function actionLogin()
    {
        if (!Yii::$app->user->isGuest) {
            return $this->goHome();
        }
        $this->setMetaData(Yii::t('head', 'Login'), Yii::t('head', 'LoginDesc'),Yii::t('head', 'LoginCont'));
        $model = new LoginForm();
        // if ($model->load(Yii::$app->request->post()) && $model->login()) {
        //     return $this->goBack();
        // } else {
        //     $model->password = '';
        //     return $this->render('login', [
        //         'model' => $model,
        //     ]);
        // }
        if(Yii::$app->request->post() && isset($_POST['LoginForm']['password']) )
        {
            if ($model->load(Yii::$app->request->post()) && $model->validate())
            {   
                if(Yii::$app->cache->exists('authenticate'))
                {
                    Yii::$app->cache->set('user', $model, 300);
                    return $this->render('login', [
                        'model' => $model,
                    ]);
                }elseif($model->login())
                {
                    return $this->goBack();
                }
            }
            echo "<pre>";print_r(Yii::$app->request->post());die;
        }
        if(Yii::$app->request->post() && isset($_POST['LoginForm']['google_auth']))
            {
                $ga = new GoogleAuthenticator;
                $secret = Yii::$app->cache->get('authenticate');
                $code = $ga->getCode($secret);
                if ($code != Yii::$app->request->post('LoginForm')['google_auth'])
                {
                    return $this->render('login', [
                        'model' => $model,
                    ]);
                }
                    // if(isset($_COOKIE['authenticate']))
                    // {
                    //     setcookie("authenticate", "", time() - 3600);
                    // }
                    $model = Yii::$app->cache->get('user');
                    if($model->login())
                    {
                        Yii::$app->cache->delete('authenticate');
                        Yii::$app->cache->delete('user');
                        return $this->goBack();
                    }
            }
        $model->password = '';
        return $this->render('login', [
                'model' => $model,
            ]);
    }

    /**
     * Logs out the current user.
     * @return mixed
     */
    public function actionLogout()
    {   if(Yii::$app->cache->exists('authenticate'))
            Yii::$app->cache->delete('authenticate');
        Yii::$app->user->logout();

        return $this->goHome();
    }

    /**
     * Displays contact page.
     * @return mixed
     */

    public function actionContacts()
    {
        $this->setMetaData(Yii::t('head', 'Contacts'), Yii::t('head', 'ContactsDesk'), Yii::t('head', 'ContactsCont'));
        return $this->render('contacts');
    }

    /**
     * Signs user up.
     * @return mixed
     */
    public function actionSignup()
    {
        $this->setMetaData(Yii::t('head', 'Sign'), Yii::t('head', 'SignDesc'), Yii::t('head', 'SignCont'));
        $model = new SignupForm();
        if ($model->load(Yii::$app->request->post())) {
            $model->setPassword($model->password_hash);
            if ($model->validate() && $model->save()) {
                return $this->goHome();
            }
        }

        return $this->render('signup', [
            'model' => $model,
        ]);
    }

    /**
     * Requests password reset.
     * @return mixed
     */
    public function actionRequestPasswordReset()
    {
        $model = new PasswordResetRequestForm();
        if ($model->load(Yii::$app->request->post()) && $model->validate()) {
            if ($model->sendEmail()) {
                Yii::$app->session->setFlash('success', 'Check your email for further instructions.');

                return $this->goHome();
            } else {
                Yii::$app->session->setFlash('error', 'Sorry, we are unable to reset password for the provided email address.');
            }
        }

        return $this->render('requestPasswordResetToken', [
            'model' => $model,
        ]);
    }

    /**
     * Resets password.
     * @param string $token
     * @return mixed
     * @throws BadRequestHttpException
     */
    public function actionResetPassword($token)
    {
        try {
            $model = new ResetPasswordForm($token);
        } catch (InvalidParamException $e) {
            throw new BadRequestHttpException($e->getMessage());
        }

        if ($model->load(Yii::$app->request->post()) && $model->validate() && $model->resetPassword()) {
            Yii::$app->session->setFlash('success', 'New password saved.');

            return $this->goHome();
        }

        return $this->render('resetPassword', [
            'model' => $model,
        ]);
    }

    public function actionSupport()
    {
        if(Yii::$app->request->post() && Yii::$app->request->validateCsrfToken())
        {
            $data['status'] = 200;
            $data['text'] = '';
            $model = new Support();
            $model->load(Yii::$app->request->post());
            $model->category = Support::CATEGORY_SUPPORT;
            $model->status = Support::STATUS_WAIT;
            if($model->save())
            {
                $data['status'] = 200;
                $data['text'] = Yii::t('site', 'Support send');
            }
            else
            {
                $data['status'] = 200;
                foreach ($model->getErrors() as $errors)
                {
                    $data['text'] = $errors[0];
                }
            }
            echo json_encode($data);
        }
    }
}

view

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

<?php

use yii\bootstrap\ActiveForm;
use yii\helpers\Html;
use yii\helpers\Url;
use frontend\models\Gallery;

?>
    <div class="col-sm-12 main">
        <!-- Banner -->
        <?php if ($events): ?>
            <div class="alert alert-info">
                <?php foreach ($events as $event): ?>
                    <p><?php echo Html::a($event['title'], Url::to([$event['url']])) ?></p>
                <?php endforeach; ?>
            </div>
        <?php endif ?>
        <section id="banner">

            <?php if ($main): ?>
                <!--            <div class="main">-->
                <div id="sidebar" class="carousel slide" data-ride="carousel">
                    <!-- Indicators -->
                    <ol class="carousel-indicators">
                        <li data-target="#sidebar" data-slide-to="0" class="active"></li>
                        <li data-target="#sidebar" data-slide-to="1"></li>
                        <li data-target="#sidebar" data-slide-to="2"></li>
                        <li data-target="#sidebar" data-slide-to="3"></li>
                    </ol>
                    <div class="carousel-inner">
                        <div class="item active">
                            <?php if ($main['newsLang']): ?>
                                <?php foreach ($main['newsLang'] as $news): ?>
                                    <?php if ($news['lang'] == Yii::$app->language): ?>
                                        <div class="col-sm-12 carousel-title"> <h3><?php echo Html::a($news['title'], Url::to(['/news/view', 'id' => $main['param']])); ?> <h3></div>
                                        <div class="col-sm-3">
                                            <?php echo Html::a('<img src="' . $main['photo'] . '">', Url::to([Yii::getAlias('@web') . '/news/view', 'id' => $main['param']])); ?>
                                        </div>

                                        <div class="col-sm-8">
                                            <h3>
                                                <?php echo Html::a($news['title'], Url::to(['/news/view', 'id' => $main['param']])); ?>
                                            </h3>
                                            <?php echo $news['content'] ?>
                                        </div>
                                    <?php endif; ?>
                                <?php endforeach; ?>
                            <?php endif; ?>
                        </div>
                        <?php if ($sidebar): ?>
                            <?php foreach ($sidebar as $item): ?>
                                <?php if ($item['newsLang']): ?>
                                    <?php foreach ($item['newsLang'] as $news): ?>
                                        <?php if ($news['lang'] == Yii::$app->language): ?>
                                            <!-- Wrapper for slides -->
                                            <div class="item">
                                                <div class="col-sm-3">
                                                    <img src="<?php echo $item['photo'] ?>">
                                                </div>
                                                <div class="col-sm-8">
                                                    <h3>
                                                        <?php echo $news['title']; ?>
                                                    </h3>
                                                    <?php echo $news['content']; ?>
                                                </div>
                                            </div>
                                        <?php endif; ?>
                                    <?php endforeach ?>
                                <?php endif; ?>
                            <?php endforeach; ?>
                        <?php endif; ?>
                    </div>
                    <?php if ($sidebar): ?>
                        <!-- Left and right controls -->
                        <a class="left carousel-control" href="#sidebar" data-slide="prev">
                            <span class="glyphicon glyphicon-chevron-left"></span>
                            <span class="sr-only">Previous</span>
                        </a>
                        <a class="right carousel-control" href="#sidebar" data-slide="next">
                            <span class="glyphicon glyphicon-chevron-right"></span>
                            <span class="sr-only">Next</span>
                        </a>
                    <?php endif ?>
                </div>
                <!--            </div>-->
            <?php endif ?>

        </section>

        <section id="two" class="wrapper alt">
            <section class="spotlight bachgorund2">
                <div class="image" style="max-width:300px"><img
                            src="<?php echo Yii::getAlias('@web') . '/images/site/archery.jpg' ?>" alt=""/></div>
                <div class="content">
                    <h2><?php echo Yii::t('site', 'Sportsmens') ?></h2>
                    <p><?php echo Yii::t('site', 'About sportsmens') ?></p>
                </div>
            </section>
            <section class="spotlight bachgorund3">
                <div class="image" style="max-width:300px"><img
                            src="<?php echo Yii::getAlias('@web') . '/images/site/coach_main.jpg' ?>" alt=""/></div>
                <div class="content">
                    <h2><?php echo Yii::t('site', 'Coach') ?></h2>
                    <p><?php echo Yii::t('site', 'About coach') ?></p>
                </div>
            </section>
            <section class="spotlight bachgorund4">
                <div class="image" style="max-width:350px"><img
                            src="<?php echo Yii::getAlias('@web') . '/images/site/fslu.jpg' ?>" alt=""/></div>
                <div class="content">
                    <h2><?php echo Yii::t('site', 'Federation') ?></h2>
                    <p><?php echo Yii::t('site', 'About federation') ?></p>
                </div>
            </section>
        </section>

        <!-- Three -->
        <section id="three" class="wrapper special">
            <div class="inner">
                <header class="major">
                    <h2><?php echo Yii::t('site', 'Photo') ?></h2>
                    <p><?php echo Yii::t('site', 'Our photo') ?></p>
                </header>
                <ul class="features">
                    <?php if (empty($gallery)): ?>
                        <li class="gallery-icon">
                            <img src="<?php echo Yii::getAlias('@web') . '/images/site/no_folder.jpeg' ?>">
                            <h4><?php echo Yii::t('site', 'No folder') ?></h4>
                        </li>
                    <?php else : ?>
                        <?php foreach ($gallery as $item): ?>

                            <li class="gallery-icon">
                                <?php echo Html::a('<img src="' .Yii::getAlias('@web') . $item['gallery']['folder_icon'] . '">', [Url::to([(new Gallery())->getUrl( $item['gallery']['category']), 'id' => $item['gallery_id']])]) ?>
                                <h4><?php echo Html::a($item['folder'], [Url::to([(new Gallery())->getUrl($item['gallery']['category']), 'id' => $item['gallery_id']])]) ?></h4>
                            </li>
                        <?php endforeach; ?>

                    <?php endif ?>
                </ul>
            </div>
        </section>

        <!-- CTA -->
        <section id="cta" class="wrapper style4">
            <h2><?php echo Yii::t('site', 'Contact us') ?></h2>
            <div class="inner">
                <header>

                    <?php $form = ActiveForm::begin(['layout' => 'horizontal', 'id' => 'support', 'enableAjaxValidation' => false, 'enableClientValidation' => false]); ?>
                    <?= $form->field($support, 'title', ['labelOptions' => ['class' => 'control-label col-sm-2'], 'wrapperOptions' => ['class' => 'col-sm-9']])->textInput(['placeholder' => Yii::t('site', 'Input title'),]) ?>
                    <?= $form->field($support, 'email', ['labelOptions' => ['class' => 'control-label col-sm-2'], 'wrapperOptions' => ['class' => 'col-sm-9']])->textInput(['placeholder' => Yii::t('site', 'Input email'),]) ?>
                    <?= $form->field($support, 'content', ['labelOptions' => ['class' => 'control-label col-sm-2'], 'wrapperOptions' => ['class' => 'col-sm-9']])->textArea(['rows' => 5, 'placeholder' => Yii::t('site', 'Input content')]) ?>
                    <div class="form-group">
                        <div class="col-sm-11">
                            <?= Html::submitButton(Yii::t('site', 'Send'), ['class' => 'btn btn-danger pull-right']) ?>
                        </div>
                    </div>
                    <?php ActiveForm::end(); ?>

                </header>
            </div>
        </section>
    </div>

<?php $script = "
$(document).on('click', '#support .btn', function (event) {
        $('.sender').remove();
        $.ajax({
            url: '" . Url::to('/site/support') . "',
            type:'post',
            data:$('#support').serialize(),
            dataType:'json',
            success: function(res)
            {
                console.log(res);
                if(res)
                {
                    $('#support')[0].reset();
                    var check = $('<div>').addClass('col-sm-12 bg-green sender').text(res.text);
                    $('#support').append(check);
                }
                else
                {
                    console.log('message was not send');
                }
            },
            error: function()
            {
                alert('Ошибка подключения!');
            }
        });
        return false;
    });
    
    $(document).on('click', '.del-langs', function () {
        $(this).closest('.add-language').remove();
	});
 
";
$this->registerJs($script, yii\web\View::POS_END);
?>
someweb
Сообщения: 552
Зарегистрирован: 2017.03.09, 10:12

Re: ajax некоректно работает

Сообщение someweb »

Замените echo json_encode($data); на return json_encode($data);
Чтобы правильно задать вопрос, нужно знать бо́льшую часть ответа. Роберт Шекли.
andku83
Сообщения: 988
Зарегистрирован: 2016.07.01, 10:24
Откуда: Харьков

Re: ajax некоректно работает

Сообщение andku83 »

c ajax все в порядке, причина ошибки в использовании ECHO в контроллере
vano.mig
Сообщения: 73
Зарегистрирован: 2016.11.21, 10:25

Re: ajax некоректно работает

Сообщение vano.mig »

спасибо, все работает!))
можно вопрос: это были изменения в структуре фреймворка или php? просто раньше через echo работали запросы
Спасибо огромное за помощь)
urichalex
Сообщения: 994
Зарегистрирован: 2015.08.07, 11:03

Re: ajax некоректно работает

Сообщение urichalex »

return $this->asJson($data);
andku83
Сообщения: 988
Зарегистрирован: 2016.07.01, 10:24
Откуда: Харьков

Re: ajax некоректно работает

Сообщение andku83 »

https://github.com/yiisoft/yii2/blob/ma ... #L365-L367 - эти изменения появились уже более года назад.
Аватара пользователя
bemulima
Сообщения: 207
Зарегистрирован: 2012.12.20, 09:41
Откуда: Курган

Re: ajax некоректно работает

Сообщение bemulima »

Так же можно установить в экшне

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

Yii::$app->response->format = yii\web\Response::FORMAT_JSON;
затем просто

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

return $data;
Ответить