WEB开发之前端与后端通信解决方案篇

看到此文,是否觉得体内洪荒之力爆发,饥渴难耐想吐槽、情不自禁想捐赠
本文为原创文章,尊重辛勤劳动,可以免费摘要、推荐或聚合,亦可完整转载,但完整转载需要标明原出处,违者必究。

支付宝微  信

每天都得找点乐子,今天的乐子就是“WEB开发中前端与后端通信的解决办法”。

首先,说一下“神圣”的需求。假设,我们面前是一个报名活动的页面。所有的逻辑都发生在这报名按钮上,下面是导图:

报名按钮导图 - 胡旭个人博客

做法一


按钮是一个链接,当我们用可爱的手指轻轻抚摸他时。他会告诉浏览器,我是一个链接。之后,浏览器被跳转到一个新的连接上。与此同时,后端会执行当前的逻辑,渲染对应的WEB页面。

这种做法很糟糕:

1、用户体验不好,跳转页面的吞吐量比较高,加大用户的等待时间

2、同时,也加大服务器的负担;

3、代码冗余度较高,需要写若干个前端页面和后端方法。

 

做法二


那么,用AJAX来实现前后端的通信(异步)也许是个不错的做法。既然,谈到通信,那么必定要有个标准。那,标准是个什么东西?

举个例子(秒懂!哈哈)

公认的标准脸型:  5E2EF8CB-6607-41E6-9B25-CB164FC2A2AB

 

不符合标准的脸型:

如花

所以,你知道。如果程序没有标准,是一件多么令人“恼怒”的事情。

 

需要两个PHP类库:

标准接口:

namespace Common\Library\Int;
/**
 * For communicating each other.
 *
 * @author genialx
 * @see ErrorMsg
 */
interface ErrorMsgInterface {

	//============//
	/* Error code */
	//============//

	/**
	 * Success.
	 *
	 * @author genialx
	 */
	const ERROR_CODE_0X0001 = 0x0001; // success.

	/**
	 * unknown error.
	 *
	 * @author genialx
	 */
	const ERROR_CODE_0X0002 = 0x0002; 

	/* Error type */
	const ERROR_TYPE_JSON	= 'json'; // for json format

}

实现类库:

namespace Common\Library\Util;
use Common\Library\Int\ErrorMsgInterface;

/**
 * For returning the message in json.
 *
 * It must implement the interface to communicate each other.
 *
 * @author genialx
 *
 */
class ErrorMsg implements ErrorMsgInterface {

	private $_errCode = '';
	private $_errMsg  = '';
	private $_type    = 'json';
	private $_return  = '';
	private $_data    = array();

	/**
	 * __call method.
	 *
	 * @author genialx
	 * @param string $methodName
	 * @param string $args
	 */
	Public function __call($methodName, $args) {
		$this->_data[$methodName] = $args[0];
		return $this;
	}

	/**
	 * Set the type.
	 *
	 * @author genialx
	 * @param unknown $type
	 */
	public function setType($type = self::ERROR_TYPE_JSON) {
		$this->_type = $type;
	}

	/**
	 * Get the type.
	 *
	 * @author genialx
	 * @return string
	 */
	public function getType() {
		return $this->_type;
	}

	public function setErrCode($errCode) {
		$this->_errCode = $errCode;
		$this->_setMsg($errCode);
	}

	/**
	 * Get the errCode.
	 *
	 * @author genialx
	 * @return string
	 */
	public function getErrCode() {
		return $this->_errCode;
	}

	/**
	 * Get set tht errMsg.
	 *
	 * @author genialx
	 * @param unknown $errMsg
	 */
	public function setErrMsg($errMsg) {
		$this->_errMsg = $errMsg;
	}

	/**
	 * Get the errMsg.
	 *
	 * @author genialx
	 * @return string
	 */
	public function getErrMsg() {
		return $this->_errMsg;
	}

	/**
	 * Get the return.
	 *
	 * @author genialx
	 * @return string
	 */
	public function getReturn() {
		if($this->_errCode == '') return $this->_getUnknowReturn();
		switch($this->_type) {
			case self::ERROR_TYPE_JSON:
				return $this->_getJSON();
			;break;
			default:
				return $this->_getUnknowReturn();
			break;
		}

	}

	/**
	 * Get the return in the json format, according to the private vars.
	 *
	 * @return string
	 */
	private function _getJSON() {
		$json = array(
				'errCode' => $this->getErrCode(),
				'errMsg'  => $this->getErrMsg()
		);
		if(count($this->_data)) {
			$json = array_merge($json, $this->_data);
		}
		return json_encode($json);
	}

	/**
	 * Get the message according to the error code.
	 *
	 * @author genailx
	 */
	private function _setMsg($errCode = null) {
		if(!isset($errCode)) {
			$errCode = $this->_errCode;
		}
		if($this->_errMsg != '') return false;
		switch($errCode) {
			case self::ERROR_CODE_0X0001:
				$this->setErrMsg('Success.');
			break;
			case self::ERROR_CODE_0X0002:
				$this->setErrMsg('Unknown error.');
			break;
			default:
				$this->setErrMsg('Uknown error.');
			break;
		}
	}

	/**
	 * Get the unknown return in json format.
	 *
	 * @author genailx
	 * @return string
	 */
	private function _getUnknowReturn() {
		$json = array("errCode"=>self::ERROR_CODE_0X0002,"errMsg"=>"Unknown error.");
		return json_encode($json);
	}

	/**
	 * Get the return of the success case.
	 *
	 * @author genailx
	 * @return string
	 */
	public function getSuccessReturn() {
		$this->_errCode = self::ERROR_CODE_0X0001;
		return $this->getReturn();
	}
}

后端:

namespace API\Controller;
use Common\Library\Util\ErrorMsg;

class Web extends Controller {

    /**
     * 参加活动.
     *
     */
    public function addActivity() {
        /* 初始化局部变量 */
        $EM = new ErrorMsg();

        // Some statements...

        if(boolean) {
            $EM->setErrCode($EM::ERROR_CODE_0X0001);
            $EM->setType($EM::ERROR_TYPE_JSON);
            $EM->setErrMsg("successful message to show.");
            $EM->getReturn();
            return true;
        } else {
            $EM->setErrCode($EM::ERROR_CODE_0X0002);
            $EM->setType($EM::ERROR_TYPE_JSON);
            $EM->setErrMsg("failed message to show.");
            $EM->getReturn();
            return false;
        }
    }

}

前端HTML:

<script type="text/javascript" src="add-activity.js"></script>
<script>
    $(function() {
        homeUrl = "__HOME_URL__";
        addActivit.init(); // 初始化操作
    });
</script>

前端Javascript:

var _homeUrl = '';

var addActivity = {

    // 注册事件
    var triggerEvents = function() {
        $("#add-button").on("touchstart", function() {
            var parameters = $("#parameters").val();
            $.get(_homeUrl + "/API/Web/addActivity?parameters=" + parameters, function(result) {
                var json = $.parseJSON(result); // 解析来自后台的json字符串
                // 根据返回码,执行相应动作
                switch(json.errCode) {
                    case 0x0001:
                        // some statements...
                        break;
                    case 0x0002:
                        // some statements...
                        break;
                    default:
                        // some statements...
                        break;
                }
            });
        });
    };

    return {
        init: function(homeUrl) {
            _homeUrl = homeUrl;
            triggerEvents(); //注册事件
        };
    };

}();

完善


当然,这个模式可以根据不同项目做少许改变。

目前,也许会遇到这样的问题。当逻辑比较复杂时,那么注册在这个”加入“按钮上的事件函数的处理逻辑会涉及多次请求服务器来判断当前的状态(是或否)。这种情况,对于编码和用户体验(延时等待)都不是好的。所以,其实也可以在报名页面渲染时,把必要的字段放在input[type='hidden']中。这样,也就页面了JS多次请求服务器的问题。

 

注:该文章代码均为伪代码,不可直接复用。文中PHP类库样例代码基于ThinkPHP框架。

 


 

文章来源:胡旭个人博客 => 【原】WEB开发之前端与后端通信解决方案篇

转载请注明出处,违者必究!


这是一篇原创文章,如果您觉得有价值,可以通过捐赠来支持我的创作~
捐赠者会展示在博客的某个页面,钱将会用在有价值的地方,思考中...


分类: PHP, 技术 | 标签: , , , , | 2个评论 | Permalink

2个评论

发表评论

电子邮件地址不会被公开。