Действие не найдено после запроса AJAX - PullRequest
0 голосов
/ 17 ноября 2018

Перед отправкой я хочу отправить запрос на действие.Но взамен я получаю 404 not found.Действие явно там.Также получил его в фильтрах контроллера.JS:

$('#home-contact').on('beforeSubmit', function(){
                    $.ajax({
                        method: 'post',
                        url: '/site/send-contact',
                        data: new FormData($(this))[0],
                        success: function(data){
                            console.log(data)                          
                        }
                    })
                    return false
                })

Фильтры контроллера:

'access' => [
                'class' => AccessControl::className(),
                'only' => ['logout', 'signup', 'send-contact'],
                'rules' => [
                    [
                        'actions' => ['signup', 'send-contact'],
                        'allow' => true,
                        'roles' => ['?'],
                    ],
                    [
                        'actions' => ['logout'],
                        'allow' => true,
                        'roles' => ['@'],
                    ],
                ],
            ],

И действие также:

public function actionSendContact()
    {
        Yii::$app->response->format = Response::FORMAT_JSON;
        $model = new Contact();
        if($model->load(Yii::$app->request->post()) && $model->save()){
            return $data['success'] = Yii::t('app', 'Successfully sent message.');
        }
        return $data['error'] = Yii::t('app', 'Something went wrong. Please try again.');
    }

Сценарий происходит во внешнем интерфейсе, если это имеет какое-то значение.Спасибо!

Ответы [ 3 ]

0 голосов
/ 18 ноября 2018

URL в JavaScript, похоже, не указан полностью.

Допустимый путь:

url: 'index.php?r=site/send-contact',

Но это работает, только если ваш index.php находится в корневой папке.

Чтобы заставить его работать с любой ситуацией (например, index.php не находится в корне), тогда у вас есть разные решения.Мне лично нравится использовать это:

  • Объявите action и id в вашей форме:

Пример:

$form = ActiveForm::begin([
    'action' => ['site/send-contact'],
    'id' => 'my-form',
]);
  • Используйте ссылку (которая генерируется самим Yii2) в вашем коде JS:

Пример:

$('#home-contact').on('beforeSubmit', function() {
    $.ajax({
        method: 'post',
        url: $('#my-form').attr('action'),
        data: new FormData($(this))[0],
        success: function(data) {
            console.log(data)                          
        }
    });

    return false;
});

Thisдолжно работать во всех случаях, когда ваши файлы.

Надеюсь, это поможет!

0 голосов
/ 18 ноября 2018

Не уверен насчет 404, которое у вас есть, поскольку URL-адрес в запросе является правильным, и URL-адрес, который будет сгенерирован для запроса ajax, будет выглядеть как http://example.com/site/send-contact, но только если вы используете 'enablePrettyUrl' => true, дляКомпонент urlManager, в противном случае он должен быть похож на index.php?r=site/index, что может быть только причиной для 404, лучше получить URL-адрес из атрибута формы action.

Помимо вышеупомянутого,

Вы используете new FormData() для отправки данных с запросом, например

data: new FormData($(this))[0] 

, что неверно и не будет отправлять FormData с запросом как таковымвернет undefined, вы можете проверить console или с помощью print_r($_POST) внутри действия sendContact, как только вы закончите с 404, это должно быть

data: new FormData($(this)[0]),

, вам нужнополучить форму через $(this)[0] и перейти на new FormData().

Но этого недостаточно, вам нужно установить contentType и processData равными false для правильной отправки FormData, или вы получите исключение в консоли

Uncaught TypeError: Недопустимый вызов

Таким образом, ваш код должен выглядеть так:

$('#contact-form').on('beforeSubmit', function(){
    let url=$(this).attr('action');
    let form=$(this)[0];
    let data=new FormData(form);

    $.ajax({
        method: 'post',
        url: url,
        data:data,
        contentType: false, // NEEDED, DON'T OMIT THIS (requires jQuery 1.6+)
        processData: false,
        success: function(data){
            console.log(data)                          
        }
    });
    return false;
})

EDIT

Примечание: Прежде всего вы должны просто использовать data:$(form).serialize() вместо new FormData() до тех пор, пока вы не планируете загружать файлы вместе с формой, используя ajax.

0 голосов
/ 17 ноября 2018

Вы добавили 'enableAjaxValidation' => true или добавили название действия в активной форме?

$form = ActiveForm::begin([
    'action' => ['controller/action'],
    'enableAjaxValidation' => true
]);
...