在一个域上,我有我的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'Controller
的beforeAction
中)。
/**
* @inheritdoc
*/
public function beforeAction($action)
{
if ($action == 'my-method') {
Yii::$app->controller->enableCsrfValidation = false;
}
return parent::beforeAction($action);
}
官方文档:
- beforeAction ()
这个答案是相关的,但我没有提到这些细节,也更新了