AJAX 请求后未找到操作

Action not found after AJAX request

在提交之前,我想将请求发送到一个操作。但是在 return 中我得到 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.');
    }

如果这在某种程度上很重要,那么这种情况就会发生在前端。谢谢!

您是否添加了 'enableAjaxValidation' => true 或添加活动形式的动作名称?

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

URL in JavaScript 似乎没有完全指定。

有效的方式是:

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

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

为了使其适用于任何情况(例如,index.php 不在 root 中),那么您有不同的解决方案。我个人喜欢用这个:

  • 在您的表单中声明 actionid

示例:

$form = ActiveForm::begin([
    'action' => ['site/send-contact'],
    'id' => 'my-form',
]);
  • 在您的 JS 代码中使用 link(由 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;
});

这应该适用于所有情况,只要您的文件在。

希望对您有所帮助!

不确定您拥有的 404,因为请求中的 url 是正确的,并且将为 ajax 请求生成的 url 将是像 http://example.com/site/send-contact 但只有当你使用 'enablePrettyUrl' => true, 作为 urlManager 组件时,否则它应该像 index.php?r=site/index 这可能只是 404 背后的原因, 更好的方法是从表单 action 属性中获取 url.

除上述之外,

您正在使用 new FormData() 发送数据以及

之类的请求
data: new FormData($(this))[0] 

这是不正确的,不会像 return undefined 那样随请求发送任何 FormData,您可以检查 console 或使用操作 sendContact 中的 print_r($_POST) 一旦完成 404,它应该是

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

您需要通过 $(this)[0] 获取表格并传递给 new FormData()

但是 这还不够,您必须将 contentTypeprocessData 设置为 false 才能正确提交 FormData 或者你会在控制台中得到异常

Uncaught TypeError: Illegal invocation

所以你的代码应该像

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

编辑

注意:最重要的是,您应该简单地使用 data:$(form).serialize() 而不是使用 new FormData(),除非您计划使用 ajax 上传文件和表格。