vdata protocol is a perfect total solution for HTTP RPC Call. It's free and open source. And, it's the best way for calling and responding HTTP services.
With pretty vdata, you will be able to easily call HTTP services with required version and timeout control. And definitely, Cross-origin resource sharing(CORS) call is okay. vdata client were now wrote in PHP and Javascript, for more features, please view documentation.

PHP : Call service at client
use dekuan\vdata\CConst;
use dekuan\vdata\CRequest;


$cRequest   = CRequest::GetInstance();
$arrResp    = [];
$nCall      = $cRequest->Post
(
    [
        'url'       => 'http://api-account.dekuan.org/login',
        'data'      =>
        [
            'u_name'    => 'username',
            'u_pwd'     => 'password',
            'u_keep'    => 1
        ],
        'version'   => '1.0',   //  required version of service
        'timeout'   => 30,      //  timeout in seconds
        'cookie'    => [],      //  array or string are both okay.
    ],
    $arrResp
);
if ( CConst::ERROR_SUCCESS == $nCall &&
    $cRequest->IsValidVData( $arrResp ) )
{
    //  arrResp
    //      'errorid'   : error id
    //      'errordesc' : error desc
    //      'vdata'     : virtual data
    //      'version'   : in-service version of service
    //      'json'      : original json array
    print_r( $arrResp );
}
                    
PHP : Respond client at server
use dekuan\vdata\CResponse;


$cResponse  = CResponse::GetInstance();

$cResponse->SetServiceName( 'vdata protocol service' );
$cResponse->SetServiceUrl( 'http://vdata.dekuan.org/vdata' );
$cResponse->Send
(
    0,                      //  error id
    "error desc",           //  error description
    [ "info" => "..." ],    //  customized info
    '1.0'                   //  in-service version of service
);
                    
PHP : Respond a CORS call at server
use dekuan\vdata\CResponse;


$cResponse  = CResponse::GetInstance();

$cResponse->SetServiceName( 'vdata protocol service' );
$cResponse->SetServiceUrl( 'http://vdata.dekuan.org/vdata' );
$cResponse->SetCorsDomains([ 'calling-domain.com' ]);
$cResponse->Send
(
    0,                      //  error id
    "error desc",           //  error description
    [ "info" => "..." ],    //  customized info
    '1.0'                   //  in-service version of service
);
                    
JS/jQuery : Call service at client
<script src="components/jquery/dist/jquery.js" ladep="1"></script>
<script src="components/vdata/dist/js/jquery/vdata.js" ladep="1"></script>
<script>
VDATA.Post
(
    {
        'url'	    : 'http://api-account.dekuan.org/login',
        'version'   : '1.0',    //  required service version
        'timeout'   : 3000,     //  timeout in milliseconds
        'async'     : true,     //  asynchronous? default is true
        'data'	    :
        {
            'u_name'    : 'username',
            'u_pwd'     : 'password',
            'u_keep'    : 1
        }
    },
    function( oJsonData )
    {
        if ( VDATA.ERROR.SUCCESS == oJsonData['errorid'] )
        {
            //  successfully
        }
        else if ( VDATA.ERROR.NETWORK == oJsonData['errorid'] )
        {
            //	network
        }
        else if ( VDATA.ERROR.EXCEPTION == oJsonData['errorid'] )
        {
            //	exception
        }
        else
        {
            //  some cases else
        }
    }
);
</script>
                    
JS/Angular : Call service at client
<script src="components/angular/angular.js" ladep="1"></script>
<script src="components/vdata/dist/js/angular/ng-vdata.js" ladep="1"></script>
<script>
angular.module
(
    'networkApp', []
)
.controller
(
    "vdataTestController",
    [
        "$scope", "vdataConst", "vdataFactory",
        function ( $scope, vdataConst, vdataFactory )
{
    $scope.PostLoginRequest = function()
    {
        vdataFactory.Post
        (
            {
                'url'       : 'http://api-account.dekuan.org/login',
                'version'   : '1.0',    //  required service version
                'timeout'   : 3000,     //  timeout in milliseconds
                'async'     : false,    //  asynchronous? default is true
                'data'	    :
                {
                    'u_name'    : 'username',
                    'u_pwd'     : 'password',
                    'u_keep'    : 1
                }
            },
            function( oJsonData )
            {
                if ( vdataConst.ERROR.SUCCESS == oJsonData['errorid'] )
                {
                    //  successfully
                }
                else if ( vdataConst.ERROR.NETWORK == oJsonData['errorid'] )
                {
                    //	network
                }
                else if ( vdataConst.ERROR.EXCEPTION == oJsonData['errorid'] )
                {
                    //	exception
                }
                else
                {
                    //  some cases else
                }
            }
        );
    };
});
</script>
                    
 
 
Install
TOP
View PHP composer package on packagist.org
Install for PHP project via composer
$ composer global require "dekuan/vdata:>=1.0"
Required for PHP project in composer.json
"require":
{
    "dekuan/vdata" : ">=1.0"
}
Install Js package via bower
$ bower install vdata
Install Js package via npm
$ npm install vdata
 
Source code
TOP
Take a look at the code on github and see what we are up to.
Or, you can use the following command to clone vdata from GitHub:
$ git clone https://github.com/dekuan/vdata.git