王骏的博客 http://blog.okbase.net/JO2000 node.js初体验(windows环境) http://blog.okbase.net/JO2000/archive/55992.html JO2000 2018/12/15 22:56:41 下载node.js
https://nodejs.org/download/release/
解压到 d:\nodejs目录下
将d:\nodejs加入到环境变量PATH下面

下载NPM模块管理
https://github.com/isaacs/npm/tags
解压到d:\npm

node d:\npm\cli.js install -gf

Hello Node.js

var http = require('http');
http.createServer(function (req, res) {
res.writeHead(200, { 'Content-Type': 'text/plain' }); res.end('Hello Node.js\n');
}).listen(2000, "127.0.0.1");
console.log('Server running at http://127.0.0.1:2000/');

打开浏览器访问 http://127.0.0.1:2000 将看到返回的页面。


------------------------------------------------

npm install -g node-gyp

编辑 binding.gyp ,放在d:\nodejs\node_modules\node-gyp 目录下,内容如下:
{
"targets": [
{
"target_name": "binding",
"sources": [ "src/binding.cc" ]
}
]
}

在d:\nodejs\node_modules\node-gyp 目录下,执行
node-gyp rebuild

 

]]>
PHP数组常用操作备忘 http://blog.okbase.net/JO2000/archive/55963.html JO2000 2018/12/5 21:22:09 添加元素
1)方式1
$arr = array();
$arr[] = 1;
$arr[] = 2;

 

2)方式2
array_push($arr,1,2,3);

 

3)在头部添加
array_unshift($arr, 'joe', 'hank');

 

4)任意位置插入
$arr = array('A', 'B', 'C');
$arr2 = 'abc';
$t = array_splice($arr, 1, 0, $arr2);


array_splice方法,参数一是被操作的数组,参数二是操作元素的索引值,参数三是长度,参数四是要替换成的元素。该方法的效果是删除$arr中以1为起始位置,长度0的连贯的元素,然后用$arr2补上。假如长度为0,那么效果就相当于在指定索引值处插入指定元素了。

 

删除元素
$array = array(0 => "a", 1 => "b", 2 => "c");
array_splice($array, 1, 1); //删除了b

 

 

数组遍历
用foreach(速度最快):
$urls= array('aaa','bbb','ccc','ddd'); 
foreach ($urls as $url){ 
echo "This Site url is $url! <br />"; 
}

 

用for:
for ($i= 0;$i< count($urls); $i++){ 
$str= $urls[$i]; 
echo "This Site url is $str.<br />"; 
}

]]>
JavaScript面向对象编程 http://blog.okbase.net/JO2000/archive/55962.html JO2000 2018/12/5 19:22:08 非闭包实现

var MyObject = function() {
    // 私有变量
    var private_v1;
    // 私有方法
    function private_func() {}
    // 特权方法
    this.getName = function() {};
    this.setName = function() {};
    // 公有属性
    this.id = 200;
    // 公有方法
    this.public_func = function() {};
    // 构造器
    this.setName(name);
}
 
MyObject.prototype = {
    // 静态公有属性
    static_public_v1 : true,
    // 静态公有方法
    static_public_func : function() {}
};

闭包实现

var MyObject = (function() {
    // 静态私有变量
    var static_private_v1 = 0;
    // 静态私有方法
    function static_private_func() {}
    // 创建类
    function _myobject(id, name) {
        // 私有变量
        var private_v1;
        // 私有方法
        function private_func() {}
        // 特权方法
        this.getName = function() {};
        this.setName = function() {};
        // 公有属性
        this.id = 200;
        // 公有方法
        this.public_func = function() {};
        // 构造器
        this.setName(name);
    }
     
    // 构建原型
    _myobject.prototype = {
        // 静态公有属性
        static_public_v1 : true,
        // 静态公有方法
        static_public_func : function() {}
    };
     
    // 返回类
    return _myobject;
})();

实例化

var test = new MyObject();
test.static_public_func()
]]>
ui-grid 鼠标移到该行显示高亮 http://blog.okbase.net/JO2000/archive/55959.html JO2000 2018/12/4 22:29:25 Html:

<!doctype html>
<html ng-app="app">
<head>
<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.4.3/angular.js"></script>
<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.4.3/angular-touch.js"></script>
<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.4.3/angular-animate.js"></script>
<script src="http://ui-grid.info/docs/grunt-scripts/csv.js"></script>
<script src="http://ui-grid.info/docs/grunt-scripts/pdfmake.js"></script>
<script src="http://ui-grid.info/docs/grunt-scripts/vfs_fonts.js"></script>
<script src="http://ui-grid.info/release/ui-grid.js"></script>
<link rel="stylesheet" href="http://ui-grid.info/release/ui-grid.css" type="text/css">
<link rel="stylesheet" href="main.css" type="text/css">
</head>
<body>

<div ng-controller="MainCtrl">
<div ui-grid="gridOptions" class="grid" ui-grid-pinning></div>
</div>

<script src="app.js"></script>
</body>
</html>

 

JS:
var app = angular.module('app', ['ngTouch', 'ui.grid', 'ui.grid.pinning']);

app.controller('MainCtrl', ['$scope', '$http', '$log', function ($scope, $http, $log) {
$scope.gridOptions = {};

$scope.gridOptions.columnDefs = [
{ name:'id', width:50, enablePinning:false },
{ name:'name', width:100, pinnedLeft:true },
{ name:'age', width:100, pinnedRight:true },
{ name:'address.street', width:150 },
{ name:'address.city', width:150 },
{ name:'address.state', width:50 },
{ name:'address.zip', width:50 },
{ name:'company', width:100 },
{ name:'email', width:100 },
{ name:'phone', width:200 },
{ name:'about', width:300 },
{ name:'friends[0].name', displayName:'1st friend', width:150 },
{ name:'friends[1].name', displayName:'2nd friend', width:150 },
{ name:'friends[2].name', displayName:'3rd friend', width:150 },
];
$scope.gridOptions.rowTemplate = '<div ng-repeat="(colRenderIndex, col) in colContainer.renderedColumns track by col.uid" ng-mouseover="grid.appScope.hoveredIndex = rowRenderIndex" ng-mouseleave="grid.appScope.hoveredIndex = null" ui-grid-one-bind-id-grid="rowRenderIndex + \'-\' + col.uid + \'-cell\'" class="ui-grid-cell" ng-class="{\'ui-grid-row-header-cell\': col.isRowHeader, \'your-hover-class\': grid.appScope.hoveredIndex === rowRenderIndex}" role="{{col.isRowHeader ? \'rowheader\' : \'gridcell\'}}" ui-grid-cell></div>';

$http.get('https://cdn.rawgit.com/angular-ui/ui-grid.info/gh-pages/data/500_complex.json')
.success(function(data) {
$scope.gridOptions.data = data;
});
}]);


CSS:
.your-hover-class {
color:red;
}

]]>
PHP判断是不是通过HTTPS访问 http://blog.okbase.net/JO2000/archive/55958.html JO2000 2018/12/4 22:28:17 有时候$_SERVER['HTTPS']是无法取得值的,保险起见应该这样:

 

$ishttps = (!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off') || $_SERVER['SERVER_PORT'] == 443;

]]>
curl_exec返回false故障一例 http://blog.okbase.net/JO2000/archive/55957.html JO2000 2018/12/4 22:26:44 curl请求http正常,请求https返回false

var_dump(curl_errno($ch)

显示 string(28) "TCP connection reset by peer"

 

加上
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
也没有效果。

 

解决:

指定SSL版本
curl_setopt($ch, CURLOPT_SSLVERSION, 6);

 

 

SSL版本对应的值如下:

CURL_SSLVERSION_DEFAULT (0)
CURL_SSLVERSION_TLSv1 (1)
CURL_SSLVERSION_SSLv2 (2)
CURL_SSLVERSION_SSLv3 (3)
CURL_SSLVERSION_TLSv1_0 (4)
CURL_SSLVERSION_TLSv1_1 (5)
CURL_SSLVERSION_TLSv1_2 (6)

]]>
Bootstrap对话框组件(bootstrap3-dialog) http://blog.okbase.net/JO2000/archive/55956.html JO2000 2018/12/4 22:25:50 程序猿友好的Bootstrap对话框组件,来源于:

http://nakupanda.github.io/bootstrap3-dialog/

 

开始使用
<link rel="stylesheet" href="__PUBLIC__/global/plugins/bootstrap-dialog/css/bootstrap-dialog.min.css" />
<script src="__PUBLIC__/global/plugins/bootstrap-dialog/js/bootstrap-dialog.min.js"></script>

 

最简单的alert
BootstrapDialog.alert('Hello world!');

 

取消掉标题行并且自动关闭
BootstrapDialog.show({
    message: '这是消息',
    onshow: function (dialogRef) {dialogRef.getModalHeader().hide();},
    onshown: function (dialogRef) {
    var id = setTimeout(function () {
    clearTimeout(id);
    dialogRef.close();
    }, 1000);
  }
});

]]>
Javascript外部函数调用AngularJS内部函数 http://blog.okbase.net/JO2000/archive/55955.html JO2000 2018/12/4 22:23:32 <!DOCTYPE html>
<html ng-app="myApp" id="myApp">
<head>
<title>Test</title>
<script src="/js/Plugins/AngularJS/angular.min.js"></script>
</head>
<body ng-controller="testController">
{{msg}}
<a href="javascript:;" id="lbtnTest">测试</a>
</body>
</html>
<script>
var app = angular.module('myApp', []);
app.controller('testController', function ($scope, $http) {
$scope.msg = 'Hello, Angular!';
$scope.getData = function () {
return 'okbase.net';
}
});
onload = function () {
document.getElementById('lbtnTest').onclick = function () {
//通过controller来获取Angular应用
var appElement = document.querySelector('[ng-controller=testController]');
//获取$scope变量
var $scope = angular.element(appElement).scope();

// 或者 var $scope = angular.element(document.getElementById("testController")).scope();

//调用msg变量,并改变msg的值
$scope.msg = 'hello world';
//上一行改变了msg的值,如果想同步到Angular控制器中,则需要调用$apply()方法即可
$scope.$apply();
//调用控制器中的getData()方法
console.log($scope.getData());
}
}
</script>


需要注意的是,在页面渲染完成后才能用element,否则会返回undefined

]]>
记一次JSP站点迁移 http://blog.okbase.net/JO2000/archive/55954.html JO2000 2018/12/4 22:21:57 1)安装JDK

下载并安装JDK

java -version可查看安装的版本

 

1.1)JAVA环境变量设置

新建系统变量JAVA_HOME 和CLASSPATH 
变量名:JAVA_HOME 
变量值:C:\Program Files\Java\jdk1.7.0
变量名:CLASSPATH 
变量值:.;%JAVA_HOME%\lib\dt.jar;%JAVA_HOME%\lib\tools.jar;
修改系统变量PATH,将;%JAVA_HOME%\bin;%JAVA_HOME%\jre\bin;添加到原来变量值的后面。

重启系统后会生效,如果不想重启,可以将字符串复制下来在命令行执行

set JAVA_HOME=D:\Program Files (x86)\Java\jdk1.7.0

set PATH=C:\Windows\system32;C:\Windows;C:\Windows\System32\Wbem;C:\Windows\System32\WindowsPowerShell\v1.0\;C:\Program Files (x86)\Microsoft SQL Server\80\Tools\Binn\;C:\Program Files\Microsoft SQL Server\90\Tools\binn\;C:\Program Files (x86)\Microsoft SQL Server\90\Tools\binn\;C:\Program Files (x86)\Microsoft SQL Server\90\DTS\Binn\;C:\Program Files (x86)\Microsoft SQL Server\90\Tools\Binn\VSShell\Common7\IDE\;C:\Program Files (x86)\Microsoft Visual Studio 8\Common7\IDE\PrivateAssemblies\;%JAVA_HOME%\bin;%JAVA_HOME%\jre\bin

 

2)安装Tomcat

如果tomcat版本相同,就直接复制过去,如果不一样需要手工修改,
修改conf目录下的server.xml
<Host name="localhost" appBase="webapps" unpackWARs="true" autoDeploy="true">
<Context docBase="应用目录名" path="" reloadable="true" />

 

3)安装数据库

 如果出现下面的错误,检查TCP/IP协议是否开启

HTTP Status 500 - Request processing failed; nested exception is org.mybatis.spring.MyBatisSystemException: nested exception is org.apache.ibatis.exceptions.PersistenceException:


SQL Server Configuration Manager
SQL Server 2005 网络配置->MSSQLSERVER的协议->TCP/IP 启用

 

4)迁移app
应用目录在webapps,将app复制过去
修改应用目录下 WEB-INF\classes\spring\spring-datasource.xml里面的数据库连接设置。

]]>
JavaScript异步函数的顺序执行 http://blog.okbase.net/JO2000/archive/55953.html JO2000 2018/12/4 22:20:38
异步函数的顺序执行有很多种方案,例如jQuery的Deferred,ES6开始有的Promise,ES7开始有的Async/Await,以及一些第3方库。注意:ES6有部分浏览器不支持,ES7有许多浏览器不支持。

 

本文采用jQuery方案。

 

这里有3个函数wait1,wait2,wait3,我们希望wait1执行完后执行wait2,再执行wait3

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
var wait1 = function(){
  var tasks = function(){
    alert("1执行完毕!");
  };
  setTimeout(tasks,3000);
};
 
var wait2 = function(){
  var tasks = function(){
    alert("2执行完毕!");
  };
  setTimeout(tasks,2000);
};
var wait3 = function(){
  var tasks = function(){
    alert("3执行完毕!");
  };
  setTimeout(tasks,1000);
};
wait1();
wait2();
wait3();

但实际上,3个函数同时运行,alert的顺序是先3,再2,最后1。

为了实现顺序执行,我们用jQuery的Deferred改写这3个函数,3个函数改写如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
var wait1 = function(){
  var dtd = $.Deferred(); //在函数内部,新建一个Deferred对象
  var tasks = function(){
    alert("1执行完毕!");
    dtd.resolve(); // 改变Deferred对象的执行状态
  };
  setTimeout(tasks,3000);
  return dtd.promise(); // 返回promise对象
};
 
var wait2 = function(){
  var dtd = $.Deferred();
  var tasks = function(){
    alert("2执行完毕!");
    dtd.resolve();
  };
  setTimeout(tasks,2000);
  return dtd.promise();
};
 
var wait3 = function(){
  var dtd = $.Deferred();
  var tasks = function(){
    alert("3执行完毕!");
    dtd.resolve();
  };
  setTimeout(tasks,1000);
  return dtd.promise();
};
 
wait1().then(wait2).then(wait3);

这样实现了1,2,3的顺序执行。

 

当我们需要在wait1,wait2,wait3全部完成后,执行某个操作,可以这样:

1
2
3
$.when(wait1(),wait2(),wait3())
  .done(function(){ alert("全部完成了!"); })
  .fail(function(){ alert("出错啦!"); });
]]>