公司内部管理系统-用YII开发中遇到的问题(更新中...)

1、YII中控制器中actionDelete方法


以前的方案,对于“删除”功能来说,我是通过<form>中的隐藏域包含id,部门名称(name)等信息,然后通过jquery的post来提交。在用YII时,对控制器中的actionDelete($id)方法有了更进一步了解。

一般YII中自动生成的actionDelete()方法如下

/**
 * Deletes a particular model.
 * If deletion is successful, the browser will be redirected to the 'admin' page.
 * @param integer $id the ID of the model to be deleted
 */
public function actionDelete($id)
{
	$this->loadModel($id)->delete();

	// if AJAX request (triggered by deletion via admin grid view), we should not redirect the browser
	if(!isset($_GET['ajax']))
		$this->redirect(isset($_POST['returnUrl']) ? $_POST['returnUrl'] : array('admin'));
}
一开始一直以为,actionDelete方法的参数$id,是通过get方式传递的。似乎CI框架中就是这样,在YII的示例中,提交的URL都是通过类似下面语句生成的

$this->createUrl('controller/action',array('id'=>$id));
所以,我在做项目中关于“部门分类”删除功能,就在想,如果这样的话(通过GET方式提交),那只要在浏览器提交相应的URL,更改id值,这样数据的安全性如何保证呢?

后来,在js中,我特意将post提交,改为get提交,代码如下:

  $(".del").bind("click",function(event){
	var id=$("input[name='id']",$(this).parents("form:first")).attr("value");
	var name=$("input[name='name']",$(this).parents('form:first')).val();
	var url=$(this).attr('href');//例如:index.php?r=controller/action&id=1
	art.dialog.confirm('你确认删除['+name+']该分类吗?',function(){
	    $.post(url,function(tips)//<------------------这里改为get
	    {
                alert('tips');
                return false;
        	var json=eval("("+tips+")");
                if(json.result=='success'){
            	    art.dialog.tips(json.msg);
            	    $(event.target).parents('ul:first').hide();
                }
                if(json.result=='error'){
                    var str='';
                    $.each(json,function(idx,item){
                    	    if(idx=='msg')
                	    str+=item;
                    });
                    art.dialog.tips(str);
                }
	    });

	});
	return false;
  });
在actionDelete方法中,echo一个字符串,并exit();结果发现,根本不执行actionDelete方法。研究了半天,最终恍然大悟,原来控制器的上面有这样一句代码:

public function filters()
{
	return array(
		'accessControl', // perform access control for CRUD operations
		'postOnly + delete', // we only allow deletion via POST request
	);
}
就是说:delete方法只能用POST方式提交。

关于YII中删除不安全的想法一下就没有了。接下来就做了一个测试,actionDelete($id),post提交和get提交,能否能获取到。

假如我通过URL:index.php?r=controller/test&id=3

public function actionTest($id)
{
	echo $id;
	exit;
}
测试结果:

POST提交,$id值为3

GET提交,$id值为3

真相终于大白。

二、CActiveForm的ajax验证

<?php $form=$this->beginWidget('CActiveForm', array(
	'id'=>'post-form',
	'enableAjaxValidation'=>true,
)); ?>
如果开启ajax验证,如上:将属性enableAjaxValidation设置为true,那么在控制器中要调用以下方法:

protected function performAjaxValidation($model)
{
	if(isset($_POST['ajax']) && $_POST['ajax']==='costcategory-form')//这里的$_POST['ajax']的值默认为表单的id
	{
		echo CActiveForm::validate($model);
		Yii::app()->end();
	}
}
在实际项目开发中遇到的问题说明一下:

1、在控制器中调用performAjaxValidation,这个方法是在数据未提交(点击submit按钮)之前所执行的,即 未提交数据时的ajax验证。

2、如果有错误,CActiveForm::validate($model);返回的是json格式的数据

3、自定义表单注意,如果要使用ajax验证,针对验证字段,比如我要对name这个字段进行ajax验证,要加上

<?php echo $form->error($model,'name'); ?>
否则,无法开启ajax验证。

4、下面对我本人有用

由于上述表单中没有submit按钮,上图中的“保存”按钮,是基于artDialog插件生成。源码如下:

function btn_restore(){
  api=art.dialog.open.api;
  api.button({
    name:'保存',
    disabled:false
  });
}

$(document).ready(function(){
  //$(document).bind("contextmenu",function(){return false;});
  setTimeout(function () {$("#name").focus()}, 240);
  var parent=art.dialog.parent,
  api=art.dialog.open.api;
  if(!api) return;
  api.button(
    {
      name:'保存',
      callback:function(){
        this.button({
          name:'保存',
          disabled:true
        });
        $.post($("#costcategory-form").attr("action"),$("#costcategory-form").serialize(),function(s){
        	var json=eval("("+s+")");
            if(json.result=='success')
            {
            	msg(1,"操作成功",true);
            }
            if(json.result=='error')
            {
                var str='';
                $.each(json,function(idx,item){
                	if(idx=='msg')
                	str+=item;
                });
                //$("#error").html(str);
                art.dialog.tips(str);
                btn_restore();
            }

        });
        return false;
      },
      focus:true
    },
    {
      name:'放弃'
    }
  );
});
所以,即使我在CActiveForm中做以下配置:

<?php
CHtml::$afterRequiredLabel=':';
$form=$this->beginWidget('CActiveForm',array(
	'id'=>'costcategory-form',//该值也是默认的$_POST['ajax']的值。
	'enableClientValidation'=>true,
	'enableAjaxValidation'=>true,
	'clientOptions'=>array(
		'validateOnSubmit'=>true
	),
));?>
当点击“保存”按钮时,无法触发enableClientValidation(客户端验证)以及validateOnSubmit

validateOnSubmit: boolean, 当表单被提交时是否执行AJAX验证。如果存在任何验证错误,表单的提交动作将被停止。默认值是false。

ajax验证的情况在:在分类名称中输入内容,鼠标在旁边空白处单击后,可触发ajax验证。但是当点击“保存”按钮时,不会触发ajax验证。具体的可通过chrome浏览器中“审查元素”->NetWork中可查看。







评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值