在AJAX请求后找不到动作

时间:2018-11-17 19:56:46

标签: yii2 yii2-advanced-app

在提交之前,我想将请求发送给操作。但是作为回报,我得到了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 :(得分:2)

不确定您所拥有的404,因为请求中的url是正确的,并且为ajax请求生成的url将类似于http://example.com/site/send-contact,但仅当您使用{ {1}}用于'enablePrettyUrl' => true,组件,否则应该像urlManager那样,仅可能是index.php?r=site/index背后的原因,一种更好的方法是从{{ 1}}属性。

除了上方,

您正在使用404发送带有

之类的请求的数据
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,否则您将在控制台中获取异常

  

未捕获的TypeError:非法调用

因此您的代码应类似于

false

编辑

注意:首先,除非您打算使用ajax将文件和表单一起上传,否则首先应简单地使用FormData而不是$('#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; })

答案 1 :(得分:0)

JavaScript中的URL似乎没有完全指定。

有效方式为:

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

但这仅在您的index.php位于根文件夹中时有效。

要使其在任何情况下均可工作(例如,index.php不在根目录中),那么您有不同的解决方案。我个人喜欢使用这个:

  • 以您的形式声明actionid

示例:

$form = ActiveForm::begin([
    'action' => ['site/send-contact'],
    'id' => 'my-form',
]);
  • 在您的JS代码中使用链接(由Yii2本身生成):

示例:

$('#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;
});

无论您使用哪种文件,这在所有情况下都应该起作用。

希望有帮助!

答案 2 :(得分:-1)

您以活动形式添加了'enableAjaxValidation' => true还是添加了动作名称?

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