Yii框架2.0 AJAX请求POST方法


Yii framework 2.0 AJAX request with POST method

在一个域上,我有我的Yii 2.0 web应用程序,在控制器中有一个处理POST请求的方法。下面是我的控制器类中的代码:

public function behaviors()
{
    return [
        'access' => [
            'class' => AccessControl::className(),
            'rules' => [
                [
                    'actions' => [
                        'my-method',
                    ],
                    'allow' => true,
                ],
            ],
        ],
         'verbs' => [
             'class' => VerbFilter::className(),
             'actions' => [
                 'my-method' => ['post'],
             ],
         ],
    ];
}
public function actionMyMethod()
{
    Yii::$app->controller->enableCsrfValidation = false;
    $response = Yii::$app->response;
    $response->format = 'yii'web'Response::FORMAT_XML;
    return ['msg' => 'OK!'];
}

在另一个域中,我有一个简单的页面(不是Yii 2.0应用程序),它使用纯JavaScript发送带有POST方法的AJAX请求。代码如下:

var xmlhttp;
if (window.XMLHttpRequest) {
     xmlhttp = new XMLHttpRequest();
} else {
     xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
}
xmlhttp.open("POST", "http://my-domain.com/controller-name/my-method", true);
xmlhttp.setRequestHeader("Content-type","application/x-www-form-urlencoded");
xmlhttp.send("id=Henry");
xmlhttp.onreadystatechange = function() {
     if (xmlhttp.readyState==4 && xmlhttp.status==200) {
          var responseXml = xmlhttp.responseXML;
          txt=" ";
          x=responseXml.getElementsByTagName("msg");
          for (i=0;i<x.length;i++) {
               txt = txt + x[i].childNodes[0].nodeValue;
          }
          alert(txt);
     }
}

每次我试图运行上面的JavaScript代码,它说POST 400(错误的请求)在控制台中。如果我将POST更改为GET,则可以正常工作。有人能告诉我我错过了什么吗?上面的代码有什么问题?

如果你想禁用CSRF验证单个动作(s),你需要在beforeAction事件处理程序中这样做,因为CSRF令牌在动作运行之前被检查(在yii'web'ControllerbeforeAction中)。

/**
 * @inheritdoc
 */
public function beforeAction($action)
{            
    if ($action == 'my-method') {
        Yii::$app->controller->enableCsrfValidation = false;
    }
    return parent::beforeAction($action);
}

官方文档:

  • beforeAction ()

这个答案是相关的,但我没有提到这些细节,也更新了