标题:NodeJS反向代理至后端数据接口 出处:刘新修 时间:Wed, 21 Sep 2016 12:36:38 +0000 作者:刘新修 地址:http://liuxinxiu.com:80/CORS_Node_Proxy/ 内容: 支持来自任何域名的Post请求,验证请求参数必须有: [name、gender] 否则直接JSON返回错误! JavaScript代码 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>\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('

It is forbidden for the URL request!

'); res.write('
NodeJs/'+process.version); res.write(' at '+req.headers.host.split(':')[0]); res.write(' Port '+req.headers.host.split(':')[1]+'
'); 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 Generated by Bo-blog 2.1.1 Release