NodeJS反向代理至后端数据接口
		
		
 2016/09/21 12:36 | by 刘新修 ]
		支持来自任何域名的Post请求,验证请求参数必须有: [name、gender] 否则直接JSON返回错误!
- var http=require('http');
 - function server(){
 - this.exec=function(route,req,res){
 - var _self=this;
 - /********** 获取客户端数组中的部分数据可向后多取 **********/
 - this.arrv=function(o,n,p){
 - var i,y,d,p;y=false;d='';
 - for(i in o){
 - if(o[i]==n&&p==undefined){i++;return o[i]};
 - if(o[i]==n&&p!=undefined&&!isNaN(p)||y){
 - var s;s=i;
 - p=Number(p);
 - if(p>0){
 - p--;s++;d+=o[s];y=true;
 - }
 - else{
 - return d;
 - }
 - }
 - }
 - };
 - /********** 请求后端时可获取单个header头内地信息 **********/
 - this.getReqHeaders=function(n){
 - if(typeof(n)=='undefined'){
 - console.log('getReqHeaders(n)变量没有定义!');
 - }else{
 - return _self.arrv(req.rawHeaders,String(n));
 - }
 - };
 - /******** 获取客户端请求的header整体头部信息 ********/
 - this.rawHeaders=function(state){
 - var json={};
 - if(!state){
 - for(var i=0;i<req.rawHeaders.length;i++){
 - var s,s=i;
 - if(i%2==0){
 - s++;json[req.rawHeaders[i]]=req.rawHeaders[s];
 - }
 - }
 - }
 - if(state){
 - for(var i=0;i<req.rawHeaders.length;i++){
 - json[i]=req.rawHeaders[i];
 - }
 - }
 - var jsonStr=JSON.stringify(json);//结果:"{'1':'a','2':'b','3':'c'}"
 - var jsonObj=JSON.parse(jsonStr); //结果:[object Object]
 - return jsonObj;
 - };
 - //接收参数 ------ sreq.on("data",function(data){});接收html中ajax传递的参数
 - req.on("data",function(data){
 - /********* 打印提示||接受数据并反向代理到后端 *********/
 - console.log("\n--->>\nReq.on('data')",req.method.toUpperCase()+" Use Proxy!");
 - /********* 使用代理||这里Post请求体是回调data *********/
 - send(route,req,res,data);
 - });
 - /********** 判断是GET请求类型||也可以代理给后端处理 **********/
 - if(req.method.toUpperCase()=="GET"){
 - var params=[];
 - //params=url.parse(request.url,true).query;
 - //params['fruit']=compute(params);
 - res.writeHeader(200,{
 - "Content-type":"text/html; charset=utf-8"
 - });
 - res.write('<h1>It is forbidden for the URL request!</h1>');
 - res.write('<hr><address>NodeJs/'+process.version);
 - res.write(' at '+req.headers.host.split(':')[0]);
 - res.write(' Port '+req.headers.host.split(':')[1]+'</address>');
 - res.end();
 - }
 - /********* 如有req.on("data",function(data){});就跳过了以下方法 ******/
 - /********* 判断是POST请求类型||提交不走代理此方法是本机处理回调 **********/
 - else if(req.method.toUpperCase()=='POSTo'){
 - var postData="";
 - /********** 读取Post提交的数据 **********/
 - req.addListener("data",function(data){
 - postData+=data;
 - });
 - /********** 数据读取完毕就会执行的监听 *********/
 - req.addListener("end",function(){
 - /********* 定义Post请求主体 *********/
 - var query=require('querystring').parse(postData);
 - /************** 判断如果有POST过来数据 *************/
 - if(query.name&&query.gender){
 - console.log('Start a request...');
 - var origin=_self.arrv(req.rawHeaders,'Origin');
 - console.log("origin:"+typeof req.rawHeaders+'---')
 - /********** 代理转发至php,跨域全放开让后端去匹配验证 **********/
 - //res.setHeader('Access-Control-Allow-Origin','*');
 - //res.setHeader('Access-Control-Allow-Headers','X-Requested-With');
 - //res.setHeader('Access-Control-Allow-Methods','GET,POST,PUT,DELETE,OPTIONS');
 - //send(route,req,res,query);
 - }
 - /****** 判断结束 ******/
 - });
 - }
 - /******** 请求后端接口 ********/
 - function send(route,req,res,data){
 - /***************************************
 - var data={
 - name:'liuxinxiu',
 - gender:"male",
 - time:new Date().getTime()
 - };
 - ****************************************/
 - //data=require('querystring').stringify(data);
 - var rawHeaders=_self.rawHeaders();
 - /********** 判断一个对象是哪中类型的对象 **********/
 - function isArray(obj){
 - return Object.prototype.toString.call(obj)==='[object Array]';
 - };
 - /********* 打印Request Headers **********/
 - console.log("\n--->>\nRequest Headers:",req.rawHeaders);
 - /***** 向后端发送请求基本的设置 *****/
 - var options={
 - port: 80,
 - host:"code.liuxinxiu.com",
 - path:'/php/Post/CORS_PHP.php',
 - method: 'POST',
 - headers:{
 - 'Content-Type':_self.getReqHeaders('Content-Type'),
 - 'Content-Length':data.length,
 - 'Origin':_self.getReqHeaders('Origin'),
 - 'User-Agent':_self.getReqHeaders('User-Agent')
 - }
 - };
 - /***** 如果header整体替换就会乱码 *****/
 - //options.headers=_self.rawHeaders();
 - var request=http.request(options,function(result){
 - console.log("\n--->>\nstatusCode:",result.statusCode);
 - console.log("\n--->>\nResponse Headers:",result.headers);
 - if(result){
 - var content_type,origin,x_powered_by,server;
 - //content_type=origin=x_powered_by=server=undefined;
 - content_type=result.headers['content-type'];
 - origin=result.headers['access-control-allow-origin'];
 - x_powered_by=result.headers['x-powered-by'];
 - server=result.headers['server'];
 - /********** 判断分别加入包含服务器错误页 **********/
 - if(origin!=undefined&&result.statusCode==200){
 - res.setHeader('Access-Control-Allow-Origin',origin);
 - }
 - if(content_type!=undefined){
 - res.setHeader('Content-Type',content_type);
 - }
 - if(x_powered_by!=undefined){
 - res.setHeader('X-Powered-By',x_powered_by);
 - }
 - if(server!=undefined){
 - res.setHeader('Server',server);
 - }
 - }
 - /********** 有异常的请求需要问题定位 **********/
 - if(result.statusCode<200||result.statusCode>206){
 - }
 - /********** 接受数据数据监听 **********/
 - var _data='';
 - result.on('data',function(chunk){
 - _data+=chunk;
 - });
 - /********** 结束接受数据监听 *********/
 - result.on('end',function(){
 - console.log("\n--->>\nresult:",_data);
 - res.write(_data);
 - res.end();
 - });
 - /******** request逻辑完成 ********/
 - });
 - request.on('error',function(e) {
 - console.log('problem with request: ' + e.message);
 - });
 - //request.write(data);
 - request.write(data+"\n");
 - request.end();
 - }
 - /****** 内部结束 ******/
 - }
 - }
 - module.exports=new server();
 
NodeJS数据接口(Post请求直接代理至后端PHP): http://liuxinxiu.com:3000/CORS_Node_Proxy/
PHP数据接口(验证跨域提交白名单外返回错误): http://code.liuxinxiu.com/php/Post/CORS_PHP.php
		
  CORS||跨域资源共享||NodeJs版本实现
		
		
 2016/09/13 21:57 | by 刘新修 ]
		使用NodeJs实现CORS 跨域资源共享,可传参origin通过限制,代码如下:
- var http=require('http');
 - var origin=require('./origin'); //调用白名单列表
 - function CORS_Node(){
 - this.exec=function(route,req,res){
 - var _self=this;
 - /************** 获取客户端origin的域名 **************/
 - origin.req=req; //白名单设置置请求头
 - origin.yes=origin.listV(); //是否在名单|true
 - origin.name=origin.getName(); //客户端ORIGIN
 - /******** 先纠正参数,参数正确后匹配白名单 ********/
 - /********** 判断是GET请求类型 **********/
 - if(req.method.toUpperCase()=="GET"){
 - var params=[];
 - //params=url.parse(request.url,true).query;
 - //params['fruit']=compute(params);
 - res.writeHeader(200,{
 - "Content-type":"text/html; charset=utf-8"
 - });
 - res.write('<h1>It is forbidden for the URL request!</h1>');
 - res.write('<hr><address>NodeJs/'+process.version);
 - res.write(' at '+req.headers.host.split(':')[0]);
 - res.write(' Port '+req.headers.host.split(':')[1]+'</address>');
 - res.end();
 - }
 - /********* 判断是POST请求类型 **********/
 - else if(req.method.toUpperCase()=='POST'){
 - var postData="";
 - /********** 读取Post提交的数据 **********/
 - req.addListener("data",function(data){
 - postData+=data;
 - });
 - /********** 数据读取完毕就会执行的监听 *********/
 - req.addListener("end",function(){
 - /********* 定义Post请求主体 *********/
 - var query=require('querystring').parse(postData);
 - /********** 给客户端返回数据自造JSON **********/
 - function getJson(status){
 - if(isNaN(status))status=-1;
 - else{status=Number(status)}
 - var _drr='{'
 - +'"status":"1",'
 - +'"name":"'+query.name+'",'
 - +'"gender":"'+query.gender+'"}';
 - var _arr='{'
 - +'"status":1,'
 - +'"url":"http://www.liuxinxiu.com/",'
 - +'"dataList":'
 - +'{'
 - +'"siteId":101,'
 - +'"title":"我的博客||Node Server",'
 - +'"images":"http://www.liuxinxiu.com/upload/2016/08/10/moren.gif",'
 - +'"indexNum":"10",'
 - +'"pageNum":"100000",'
 - +'"tagNum":"22",'
 - +'"linkType":"linkTaobao",'
 - +'"publishTime":"23:15:30"'
 - +'}'
 - +'}';
 - this._dr=JSON.parse(_drr);this._ar=JSON.parse(_arr);
 - this._dt=this._dr;this._dt.getUser=this._ar;
 - }
 - var errStr={"status":-1,"info":"Request Error"};
 - /********** 先初步设置头信息,跨域全放开稍后再进行匹配验证 **********/
 - var content_type,content_length,
 - content_type='application/json; charset=utf-8';
 - content_length=Buffer.byteLength(res,'utf8');
 - res.setHeader('Access-Control-Allow-Origin','*');
 - res.setHeader('Access-Control-Allow-Headers','X-Requested-With');
 - res.setHeader('Access-Control-Allow-Methods','GET,POST,PUT,DELETE,OPTIONS');
 - res.setHeader('Content-Type',content_type);
 - res.setHeader('Server','NodeJs/'+process.version);
 - /************** 判断如果有POST过来规范的数据 *************/
 - if(query.name&&query.gender){
 - //调用数据
 - getJson(1);
 - /******** 匹配客户端域名是否在数组列表中 ******/
 - //if(_self.in_array(origin,allow_origin)){
 - if(origin.yes){
 - res.setHeader('Access-Control-Allow-Origin',origin.name);
 - res.end(JSON.stringify(_dt));
 - }
 - else{
 - /******** 如有设置就取设置URL返回头信息 ********/
 - if(query.origin){
 - res.setHeader('Access-Control-Allow-Origin',query.origin);
 - res.end(JSON.stringify(_dt));
 - }
 - /******** 没设置URL就返回无权限错误信息 ********/
 - else{
 - errStr.info="You don't have permission to submit!";
 - res.setHeader('Access-Control-Allow-Origin',origin.name);
 - res.end(JSON.stringify(errStr));
 - }
 - }
 - }
 - /********* 没有所匹配的POST提交数据||都要设头返回信息 ********/
 - else{
 - /******** 其他POST参数的提交 ********/
 - if(query){
 - res.writeHeader(res.statusCode,{
 - "Access-Control-Allow-Origin":origin.name,
 - "Access-Control-Allow-Headers":"X-Requested-With",
 - "Access-Control-Allow-Methods":"GET,POST,PUT,DELETE,OPTIONS",
 - "Content-type":"application/json; charset=utf-8"
 - });
 - var err={status:-1,info:"Syntax error in parameters or arguments."};
 - res.end(JSON.stringify(err));
 - }
 - else{
 - res.writeHeader(res.statusCode,{
 - "Content-type": "text/html; charset=utf-8"
 - });
 - res.end('It is forbidden for the URL request!');
 - }
 - }
 - /****** 判断结束 ******/
 - });
 - }
 - /****** 内部结束 ******/
 - }
 - }
 - module.exports=new CORS_Node();
 
NodeJs数据提交接口地址 (不允许使用GET访问) :http://liuxinxiu.com:3000/CORS_Node/
注意:NodeJs Server 是本站的测试环境,有时候因需要会临时关闭,该地址仅供测试,如您有需要请自建环境~
配合HTML代码如下:
- <!DOCTYPE html>
 - <html>
 - <head>
 - <meta charset="utf-8"/>
 - <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1" />
 - <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no"/>
 - <meta name="format-detection"content="telephone=no">
 - <meta name="apple-mobile-web-app-capable" content="yes" />
 - <meta name="apple-mobile-web-app-status-bar-style" content="black" />
 - <style>body,html {background:#fff;font-family: "Lucida Grande",Calibri,Arial;font-size:12pt;color: #333;background: #f8f8f8;text-align:center;}*{margin:0;padding:0;}h1{line-height:1.6em;font-size:24px;text-indent:.5em;padding-top:.6em}i{line-height:2em;font-size:18px;color:#999;}.line{height:10px;border-bottom:1px solid #ccc;font-size:0;overflow:hidden;}</style>
 - <title>跨域测试</title>
 - </head>
 - <body>
 - <h1 id="show"></h1>
 - <input type="button" value="Click me" onclick="msg()" />
 - </body>
 - <script src="//code.jquery.com/jquery-1.11.3.min.js"></script>
 - <script type='text/javascript'>
 - /********** 获取URL参数 **********/
 - function getQueryString(name){
 - var reg=new RegExp("(^|&)"+name+"=([^&]*)(&|$)","i");
 - var r=window.location.search.substr(1).match(reg);
 - if (r!=null) return unescape(r[2]); return null;
 - }
 - var _n=getQueryString('n');
 - var _url=getQueryString('url');
 - var _name=getQueryString('name');
 - var _gender=getQueryString('gender');
 - var _origin=getQueryString('origin');
 - var _error=getQueryString('error');
 - console.log('origin:'+_origin+' —— name:'+_name+' —— gender:'+_gender);
 - window.onload=function(){
 - if(_n=='php'){
 - location.href='http://'
 - +location.host
 - +location.pathname
 - +'?origin=http://'+location.host;
 - }else if(_n=='node'){
 - location.href='http://'
 - +location.host
 - +location.pathname
 - +'?origin=http://'+location.host+'&'
 - +'url=http://liuxinxiu.com:3000/CORS_Node/'
 - }else if(_n=='proxy'){
 - location.href='http://'
 - +location.host
 - +location.pathname
 - +'?origin=http://'+location.host+'&'
 - +'url=http://liuxinxiu.com:3000/CORS_Node_Proxy/'
 - }else if(_n=='test'){
 - location.href='http://test1.liuxinxiu.com/php/Interface/html/server.html'
 - +'?origin=http://test1.liuxinxiu.com&'
 - +'url=http://liuxinxiu.com:3000/CORS_Node_Proxy/&'
 - +'error=1'
 - }
 - }
 - /********** 发起Ajax请求 **********/
 - function msg(){
 - /******* 动态切换提交数据 *******/
 - if(_origin&&!_error){
 - if(_name&&_gender){
 - var data={name:_name,gender:_gender,origin:_origin};
 - }
 - else{
 - var data={name:"xiaoming",gender:"male",origin:_origin};
 - }
 - }
 - else if(_error==null){
 - var data={name:"xiaoming",gender:"male"};
 - }
 - else if(_error){
 - var data={xxx:111};
 - }
 - /******* 动态设置提交URL *******/
 - if(_url){
 - var urlPath=_url;
 - }
 - else{
 - var urlPath='http://code.liuxinxiu.com/php/Post/CORS_PHP.php';
 - }
 - $.ajax({
 - type:'post',
 - url:urlPath,
 - data:data,
 - cache:false,
 - dataType:'json',
 - success:function(data){
 - if(data.name){
 - document.getElementById("show").innerHTML=data.name+' '+data.gender;
 - }
 - else if(data.status!=1){
 - document.getElementById("show").innerHTML=data.info;
 - }
 - },
 - error:function(){
 - console.log("请求错误//")
 - }
 - });
 - };
 - /***********************************************************************************************
 - $.post("http://www.server.com/server.php",{name:"fdipzone",gender:"male"}).done(function(data){
 - document.getElementById("show").innerHTML=data.name+' '+data.gender;
 - });
 - **********************************************************************************************/
 - </script>
 - </html>
 
HTML访问地址 (测试跨域) ==> http://test1.liuxinxiu.com/php/Interface/html/server.html?n=node
HTML访问地址 (非法参数) ==> http://test1.liuxinxiu.com/php/Interface/html/server.html?error=node
注意:本站的 NodeJs Server 是学习测试环境,有临时关闭的可能,建议在本地环境测试~
		
 NodeJs JSONP数据接口定义
		
		
 2016/09/06 18:09 | by 刘新修 ]
		- var http = require('http');
 - var urllib = require('url');
 - var port = 10011;
 - var data = {'name': 'jifeng', 'company': 'taobao'};
 - http.createServer(function(req, res){
 - var params = urllib.parse(req.url, true);
 - console.log(params);
 - if (params.query && params.query.callback) {
 - //console.log(params.query.callback);
 - var str = params.query.callback + '(' + JSON.stringify(data) + ')';//jsonp
 - res.end(str);
 - } else {
 - res.end(JSON.stringify(data));//普通的json
 - }
 - }).listen(port, function(){
 - console.log('server is listening on port ' + port);
 - })
 
自建Node路由Jsonp接口访问地址:http://liuxinxiu.com:3000/jsonp?Jsoncallback=2016&&name=liuxinxiu
- function jsonp(){
 - this.exec=function(route,req,res){
 - var data1={key:'value',hello:'world',name:'刘新修'};
 - var data2={'name':'wangjiang','company':'taobao'};
 - console.log(req+'---'+route)
 - res.statusCode=200;
 - //res.setHeader('content-type','application/json;charset=utf-8');
 - //res.setHeader('Content-Type','text/html');
 - //req.write(data);
 - //req.end();
 - var params=url.parse(req.url,true);
 - console.log(params);
 - if(params.query&¶ms.query.Jsoncallback){
 - console.log(params.query.Jsoncallback);
 - var str=params.query.Jsoncallback+'('+JSON.stringify(data1)+')';//jsonp
 - res.end(str);
 - }
 - else{
 - res.writeHead(200,{'Content-Type':'application/json'});
 - res.end(JSON.stringify(data1)); //普通的json
 - }
 - }
 - }
 - module.exports=new jsonp();
 
自建Node路由Jsonp接口访问地址:http://liuxinxiu.com:3000/Jsoncallback?Jsoncallback=1&name=Jack
- function jsoncallback(){
 - this.exec=function(route,req,res){
 - /******** 处理请求判断用作JSONP ********/
 - var params=url.parse(req.url,true);
 - /********** 造数据要Obj不要String **********/
 - var str2={dataList:[{name:"Jack",age:28,sex:1},{name:'Tony',age:30,sex:0}]};
 - /********** 映射数据源无为undefined **********/
 - var output=2016+'('+JSON.stringify(str2)+')';
 - var result=params.query.Jsoncallback+'('+JSON.stringify(str2)+')';
 - /************* 定义头部信息及编码规范 *******************/
 - res.writeHead(200,{'content-Type':'application/json;charset=utf-8'});
 - /************* 判断出来相应返回的结果 ********************/
 - if(params.query&¶ms.query.Jsoncallback){
 - res.write(result);
 - res.end();
 - }
 - else{
 - res.write(output);
 - res.end();
 - }
 - }
 - };
 - module.exports=new jsoncallback();
 
渲染html到页面中,在koa中可以这么干:
- app.get('/',function*(){
 - this.body = "<p>'+title+'</p>";
 - })
 
但问题很大,模板混入到js逻辑了,非常不利于维护,基于 mvc 模式,我们需要将html模板抽离到 view 中方便维护,这时候我们就需要一款模板渲染引擎。
为什么选择xtemplate
适用于 koa 的模板引擎选择非常多,比如 jade、ejs、nunjucks、xtemplate 等。
为什么选择 xtemplate 呢?
上手难度
jade 无疑是最独特,上手难度最高,特别是将 html 转成 jade 风格的代码,需要一些成本和适应,特别是空格敏感,经常引起模块渲染报错:
- body
 - h1 Jade - node template engine
 - #container.col
 - if youAreUsingJade
 - p You are amazing
 - else
 - p Get on it!
 
但 jade 在 express 中拥有广泛的群众基础,所以从 express 转到 koa,jade 是个不错的选择,但我一直认为 jade 不是最佳的模板选择。
ejs、nunjucks、xtemplate 的上手难度差不多,但ejs的扩展写法有些诡异,特别是 filter 的写法:
- <p><%=: users | first | capitalize %></p>
 
xtemplate 相对于 nunjucks 的优势是,模板的逻辑写法体验更接近js(ejs的逻辑表达也很接近js),上手更为简单,来看下同样一个 if 判断的写法差异。
xtemplate:
- {{#if(variable===0)}}
 - It is true
 - {{/if}}
 
nunjucks:
- {% if variable == 0 %}
 - It is true
 - {% endif %}
 
所以上手难度:xtemplate < nunjucks < ejs < jade 。
功能的强大度
四款模板引擎必备几样功能都具备:变量、逻辑表达式、循环、layout、include、宏、扩展等。
nunjucks 无疑是功能最全面的模板引擎,xtemplate 拥有 nunjucks 大部分的特性,除了filter,但 xtemplate 拥有非常强悍的拓展性:
- xtpl.addCommand('money',function(scope, option){
 - var money = option.params[0];
 - if(typeof money !== 'number') return '';
 - //金额除以100(接口返回的金额都是以分为单位,转成元)
 - var s = Number(money)/100;
 - return s;
 - })
 
模板中使用:
- {{money(10000)}}
 
nunjucks 与 xtemplate 都拥有实用的宏定义功能:
- {{#macro("test","param", default=1)}}
 - param is {{param}} {{default}}
 - {{/macro}}
 
模板中使用:
- {{macro("test","2")}}
 
输出内容:
- param is 2 1
 
jade 中的 Mixins,ejs 中的 function 也可以实现类似的抽取公用html代码块的目的 。
如果真要分个高下:nunjucks > xtemplate > jade > ejs 。
是否支持前后端混用
jade 直接淘汰,相信在前端js领域一般不会选择 jade 来渲染。
nunjucks 也使用的比较少(ejs其实也少),更多人会选择使用 handlebars 。
xtemplate 目前在阿里的系统中前后端混用中已经得到论证,节约了模板前后端转换的时间。
事实上是否支持前后端混用不是决定性因素,特别是在 angularjs 盛行的年代。
性能考量
它们都很快,其实性能都不是问题,真要较真的话,xtemplate 会更优秀些,可以看 xtemplate benchmark。
个人觉得性能不是决定性因素。
基于上述几点考虑,推荐使用 xtemplate 。
		
 node.js 获取http url路径中的各个参数
		
		
 2016/09/05 08:52 | by 刘新修 ]
		假设URL为:http://localhost:8888/select?name=a&id=5
- http.createServer(function(request,response){
 - var pathname = url.parse(request.url).pathname; //pathname => select
 - var arg = url.parse(request.url).query; //arg => name=a&id=5
 - console.log("Request for " + arg );
 - var str = querystring.parse(arg); //str=> {name:'a',id:'5'}
 - var arg1 = url.parse(request.url, true).query; //arg1 => {name:'a',id:'5'}
 - console.log("Request for " + arg1 );
 - var name = querystring.parse(arg).name; //name => a
 - console.log("name = "+name);
 - console.log("Request for " + pathname + " received.");
 - }).listen(8888);
 
//querystring.parse(arg) => { name: 'a', id: '5' }
var url = require('url');
var a = url.parse('http://example.com:8080/one?a=index&t=article&m=default');
console.log(a);
 
//输出结果:
{ 
    protocol : 'http' ,
    auth : null ,
    host : 'example.com:8080' ,
    port : '8080' ,
    hostname : 'example.com' ,
    hash : null ,
    search : '?a=index&t=article&m=default',
    query : 'a=index&t=article&m=default',
    pathname : '/one',
    path : '/one?a=index&t=article&m=default',
    href : 'http://example.com:8080/one?a=index&t=article&m=default'
}
		
 nodeJs构建一个HttpServer
		
		
 2016/09/04 20:19 | by 刘新修 ]
		将下面代码放入server.js中
- var http = require("http");
 - http.createServer(function(request, response) {
 - console.log('request received');
 - response.writeHead(200, {"Content-Type": "text/plain"});
 - response.write("Hello World");
 - response.end();
 - }).listen(8888);
 - console.log('server started');
 
执行node server.js 
打开http://localhost:8888/,页面显示Hello World 
- var http=require('http');
 - var data={key:'value', hello:'world'};
 - var srv=http.createServer(function (req, res) {
 - res.writeHead(200,{'Content-Type': 'application/json'});
 - res.end(JSON.stringify(data));
 - });
 - srv.listen(8080,function() {
 - console.log('listening on localhost:8080');
 - });
 
		
 nodejs 提供了一个 node-uuid 模块用于生成 uuid:
		
		
 2016/09/04 14:07 | by 刘新修 ]
		首先执行:npm install node-uuid -g
- var uuid = require('node-uuid');
 - //var uuid = require('/usr/local/nodejs/lib/node_modules/node-uuid');
 - console.log(uuid.v1())
 - console.log(uuid.v4())
 
注明:如果在linux下编译安装node可以使用软连接ls 或这直接写绝对路径引入需要的nmp模块!
v1 是基于时间戳生成uuid
v4是随机生成uuid
结果:
- 57af5b10-3a76-11e5-922a-75f42afeee38
 - f3917fb9-9bde-4ec1-a7cf-966251b3d22a
 
		
 gcc-4.4.7升级至gcc-5.3.0 后编译安装node-v4.5.0
		
		
 2016/09/02 15:19 | by 刘新修 ]
		yum -y install gcc gcc-c++
		
 前端开发工程化—— webpack 的搭建与配置
		
		
 2016/06/12 17:48 | by 刘新修 ]
		webpack 是一个npm包,所以我们通过 npm 命令来全局安装:
.gif)

- var path=require("path");
 - var webpack=require('webpack');
 - var ExtractTextPlugin=require("extract-text-webpack-plugin");
 - /**** webpack.config.js ****/
 - module.exports={
 - context:__dirname+'/assets', //requre('a.js')的时候从哪个路径查找
 - entry:{
 - main:__dirname+"/assets/js/public/main.js",
 - index:__dirname+"/assets/js/public/index.js"
 - },
 - /**** 新添加的module属性 ****/
 - output:{
 - path:__dirname+'/build/js/',
 - filename:'[name].bundle.js', //模版基于entry的key
 - publicPath:"/xfile/" //引用你的文件时考虑使用的地址(可设成http地址, 如:http://cdn.my.com)
 - },
 - /**** 新添加的module属性 ****/
 - module:{
 - loaders:[
 - {
 - test:/\.(jpg|png|svg)$/i,
 - loaders:[
 - 'image?...',
 - 'url?limit=10000&name=img/[name].[hash:8].[ext]',
 - ]
 - },
 - {
 - test:/\.js$/,
 - exclude:/(node_modules|bower_components)/,
 - loader:'babel',
 - query:{
 - presets:['es2015'],
 - plugins:['transform-runtime']
 - }
 - },
 - {test: /\.css$/,loader: ExtractTextPlugin.extract("style-loader","css-loader")},
 - {test: /\.(jpg|png|svg)$/,loader:"url?limit=8192"},
 - {test: /\.scss$/, loader:"style!css!sass"}
 - ]
 - },
 - plugins:[
 - //new webpack.optimize.CommonsChunkPlugin('common.js'),
 - new ExtractTextPlugin("[name].css"),
 - new webpack.ProvidePlugin({
 - "jQuery":path.resolve(
 - __dirname,
 - "js/lib/jquery/jquery-1.8.3.js"
 - ),
 - "$":path.resolve(
 - __dirname,
 - "js/lib/jquery/jquery-1.8.3.js"
 - )
 - }),
 - ]
 - }
 
		
 Express.js 构建工程实例 ---- [ 环境安装、控制器/路由设置、Post+Jsonp接口、ejs模版、全局变量 ]
		
		
 2016/05/28 21:40 | by 刘新修 ]
		Express.js 构建工程实例 ---- [ 环境安装、控制器/路由设置、Post+Jsonp接口、ejs模版、全局变量 ]
ExpressJS在Node环境上安装( 绿色版Node运行环境套件下载 ):
app.js 代码如下:
- /******************************************************
 - *************** global modules ******************
 - ******************************************************/
 - var express=require('express');
 - var path=require('path');
 - var favicon=require('serve-favicon');
 - var logger=require('morgan');
 - var cookieParser=require('cookie-parser');
 - var bodyParser=require('body-parser');
 - var routes=require('./routes/index');
 - //var redis=require('./routes/redis');
 - var app=express();
 - /******************************************************
 - *************** view engine setup ******************
 - ******************************************************/
 - /****************** jade模版 *********************/
 - /*******************************************************
 - app.set('views',path.join(__dirname,'views/jade/'));
 - app.set('view engine','jade'); //jade or ejs
 - ********************************************************/
 - /****************** ejs模版 *********************/
 - app.set('views',path.join(__dirname,'views/ejs/'));
 - app.set('view engine','ejs'); //jade or ejs
 - /****************** ejs模版 *********************/
 - /******************************************************
 - ****************** routes setup ********************
 - ******************************************************/
 - // uncomment after placing your favicon in /public
 - //app.use(favicon(path.join(__dirname, 'public', 'favicon.ico')));
 - app.use(logger('dev'));
 - app.use(bodyParser.json());
 - app.use(bodyParser.urlencoded({extended:false}));
 - app.use(cookieParser());
 - app.use(express.static(path.join(__dirname,'public')));
 - app.use('/',routes);
 - /****************** routes setup *********************/
 - /*******************************************************
 - app.use('/redis',redis);
 - app.use('/jsonp',routes);
 - app.use('/login',routes);
 - *************************************************/
 - /******************************************************
 - ****************** 服务错误处理 ********************
 - ******************************************************/
 - /***** catch 404 and forward to error handler *****/
 - app.use(function(req,res,next){
 - var err=new Error('404 Not Found');
 - err.status=404;
 - next(err);
 - });
 - // error handlers
 - // development error handler
 - /***** 通用错误处理程序 *****/
 - if(app.get('env')==='development'){
 - app.use(function(err,req,res,next){
 - res.status(err.status||500);
 - res.render('sys/error',{
 - message:err.message,
 - error:err,
 - version:process.version
 - });
 - });
 - }
 - // production error handler
 - // no stacktraces leaked to user
 - app.use(function(err,req,res,next){
 - res.status(err.status||500);
 - res.render('sys/error',{
 - message:err.message,
 - error:{}
 - });
 - });
 - /***** 通用错误处理程序 *****/
 - module.exports=app;
 
routes/index.js 代码如下:
- /******************************************************
 - *************** router *************************
 - ******************************************************/
 - var express=require('express');
 - var router=express.Router();
 - var url=require("url"); //解析GET请求
 - var query=require("querystring"); //解析POST请求
 - /************* GET home page demo *************/
 - router.get('/',function(req,res,next){
 - res.render('sys/index',{title:'Express'});
 - });
 - router.get('/jsonp',function(req,res,next){
 - res.render('main/jsonp',{
 - title:'jsonp'
 - });
 - });
 - router.get('/login',function(req,res,next){
 - res.render('main/login',{
 - title:'The Entrar-shadow Website',
 - fonts:'Member Login',
 - username:'Liuxinxiu',
 - });
 - });
 - router.get('/test_load',function(req,res,next){
 - var build=req.query.build;
 - res.render('test/test_load',{
 - title:'build',
 - build:build
 - });
 - });
 - router.get('/test_page',function(req,res,next){
 - var build=req.query.build;
 - res.render('test/test_page',{
 - title:'test_page',
 - build:build
 - });
 - });
 - /*
 - app.get('/jsonp',function(req,res,next){
 - res.jsonp({status:'jsonp'});
 - });
 - */
 - /************* 自造Json数据 *************/
 - var userData='PHN0eWxlPip7bWFyZ2luOjA7cGFkZGluZzowO31oMXtmb250LXNpemU6MTZweDt0ZXh0LWFsaWduOmNlbnRlcjsgbGluZS1oZWlnaHQ6NDVweDt9Ym9keXtjb2xvcjojMzMzO2ZvbnQtc2l6ZToxNHB4O2ZvbnQtZmFtaWx5OiJNaWNyb3NvZnRZYWhlaSI7YmFja2dyb3VuZDojQjdDQUNDO31kaXZ7Ym9yZGVyOjFweCBzb2xpZCAjNDA1RTdCOyBib3JkZXItYm90dG9tOjA7IHdpZHRoOjk1JTsgbWFyZ2luOjAgYXV0bztiYWNrZ3JvdW5kOiNmZmY7Y29udGVudDoiIjtkaXNwbGF5OnRhYmxlO2NsZWFyOmJvdGh9bGl7bGluZS1oZWlnaHQ6MzVweDtsaXN0LXN0eWxlOm5vbmU7d2lkdGg6MjUlO3RleHQtYWxpZ246Y2VudGVyO2JvcmRlci1ib3R0b206MXB4IHNvbGlkICM0MDVFN0I7ZmxvYXQ6bGVmdDt9PC9zdHlsZT48aDE+5pyA6L+R6aOO5LqR5Lq65ZGY5ZCN5Y2VPC9oMT48ZGl2Pg0KCTx1bD4NCgkJPGxpPumjjua4heaJrDwvbGk+DQoJCTxsaT4xMTAxPC9saT4NCgkJPGxpPjIzPC9saT4NCgkJPGxpPjUyODE5OTExPC9saT4NCgk8L3VsPg0KCQ0KCTx1bD4NCgkJPGxpPuiuuOW/l+mjnjwvbGk+DQoJCTxsaT4xMTAxPC9saT4NCgkJPGxpPjIzPC9saT4NCgkJPGxpPjUyODE5OTExPC9saT4NCgk8L3VsPg0KCQ0KCTx1bD4NCgkJPGxpPuS7pOeLkOWGsjwvbGk+DQoJCTxsaT4xMTAyPC9saT4NCgkJPGxpPjIxPC9saT4NCgkJPGxpPjUyODE5OTAxPC9saT4NCgk8L3VsPg0KCQ0KCTx1bD4NCgkJPGxpPuS7u+aIkeihjDwvbGk+DQoJCTxsaT4xMTAzPC9saT4NCgkJPGxpPjIyPC9saT4NCgkJPGxpPjUyODE5OTkxPC9saT4NCgk8L3VsPg0KCQ0KCTx1bD4NCgkJPGxpPuS7u+ebiOebiDwvbGk+DQoJCTxsaT4xMTA0PC9saT4NCgkJPGxpPjI0PC9saT4NCgkJPGxpPjUyODE5OTgxPC9saT4NCgk8L3VsPg0KCQ0KCTx1bD4NCgkJPGxpPuS4nOaWueS4jei0pTwvbGk+DQoJCTxsaT4xMTA1PC9saT4NCgkJPGxpPjI2PC9saT4NCgkJPGxpPjUyODE5OTgxPC9saT4NCgk8L3VsPg0KCTwvZGl2Pg==';
 - var dataJson={status:1,message:"这是一个JSONP接口,success!",dataList:userData,JsonArray:[0,1,2,3,4,5]};
 - /************* 处理GET请求(jsonp需判断参数单独处理) *************/
 - router.get('/API/sendGet/jsonpInfo.do',function(req,res){
 - //res.contentType('json');//返回的数据类型
 - //res.writeHead(200,{"Content-Type":"text/json"});
 - res.setHeader('Content-Type','text/json;charset=UTF-8');
 - var params=url.parse(req.url,true).query; //解释url参数部分name=zzl&email=zzl@sina.com
 - /**** 获取请求过来的跨域回调函数名称 ****/
 - var reqQuery=req.query,Jsoncallback=req.query.Jsoncallback;
 - /**** 如果有Jsoncallback的情况 ****/
 - if(reqQuery&&Jsoncallback){
 - //console.log(params.query.Jsoncallback);
 - //res.jsonp({status:200,message:"这是一个JSONP接口",data:[]});
 - //res.send(JSON.stringify({status:200,message:"success!这是一个JSONP接口",data:[]}));
 - /**** 拼成一个JS字符串 ****/
 - var str=Jsoncallback+'('+JSON.stringify(dataJson)+')';
 - //res.json(str);
 - //res.write(str);
 - res.end(str);
 - }
 - /**** 没有Jsoncallback的情况 ****/
 - else{
 - res.json({status:200,message:"这是一个JSON接口",data:[]});
 - }
 - });
 - /************* 处理POST请求(Body/x-www-form-urlencoded) **************/
 - router.post('/API/sendPost/loginSubmit.do',function(req,res){
 - var username=req.body.username;
 - var password=req.body.password;
 - //console.log(username!='');
 - if((username&&password!='')){
 - console.log("Username="+username+",password="+password);
 - /**********************************************************************************
 - /************** JSON.stringify(v) 和 res.json 都是格式数据 ********************/
 - /*********************************************************************************
 - res.json({status:1,info:"数据提交成功!",username:JSON.stringify(username)});
 - /*********************************************************************************/
 - res.json({status:1,info:"数据提交成功!",username:username});
 - }else{
 - res.end("0");
 - }
 - });
 - module.exports=router;
 
ejs 模版:
- <!DOCTYPE html>
 - <html>
 - <head>
 - <title>test</title>
 - <meta charset="utf-8">
 - <link type='text/css' href="/css/login/home.css" rel='stylesheet' />
 - <meta name="viewport" content="width=device-width, initial-scale=1">
 - </head>
 - <body>
 - <h1>test/build=</h1>
 - <%if(1+1===2){%>
 - <h1><%= build %></h1>
 - <%}%>
 - </body>
 - <%if(build==null){%>
 - <!-- 引入require.js和入口文件||默认开放环境 -->
 - <script src="http://localhost:3000/js/lib/require.js" data-main="http://127.0.0.1:3000/js/test/app_page.js"></script>
 - <!--<script src="http://localhost:3000/js/test/yy.js"></script>-->
 - <%}%>
 - <%if(build!=null&&build==1){%>
 - <!-- 引入require.js和入口文件||判断参数用于测试build后生产环境版本js -->
 - <script src="http://localhost:3000/js/lib/require.js" data-main="http://127.0.0.1:3000/js/test-built/test/app_page.js"></script>
 - <%}%>
 - </html>
 


  
 
 
 
 
 


