NODE代理接入1.场景本地开发,代理接入,防止跨域(一般通过webpack配置代理),特殊情况比如携带一些自定义登录cookie,需要通过自己在中间层,单线程异步可以缓解服务器压力。长链接的websockets通常使用node2来搭建,node-koa2技术框架体积小,轻巧易用。Routingkoa-routerkoa支持路由,中间件支持asynckoa2-request基于request的async封装,这里我是在git上找到的,出于可靠性的考虑,如果基于生产环境,建议使用request自行封装koa-bodyparser请求参数解析和格式化-中间件3.以上代码3.1创建应用app.jsconstkoa=require('koa')constbodyParser=require('koa-bodyparser')//routingconstrouter=require('./router')constapp=newKoa()app.use(bodyParser({//返回的对象是键值对,当extended为false时,键值对中的值为'String'或'Array'。当它为真时,可以是任何数据类型。extended:true}))3.2允许跨域app.jsapp.use(async(ctx,next)=>{ctx.set('Access-Control-Allow-Origin','*')ctx.set('Access-Control-Allow-Headers','content-type')ctx.set('Access-Control-Allow-Methods','OPTIONS,GET,HEAD,PUT,POST,DELETE,PATCH')awaitnext()})3.2使用路由//app.jsapp.use(router.routes())//router.jsconstRouter=require('koa-router')letkoaRequest=require('./httpRequest')constrouter=newRouter()router.get('/*',async(ctx,next)=>{consturl=setQuestUrl(ctx.url)try{letres=awaitkoaRequest(url,'GET',ctx)ctx.body=res}catch(err){ctx.body=err}})router.post('/*',async(ctx,next)=>{consturl=setQuestUrl(ctx.url)try{letres=awaitkoaRequest(url,'POST',ctx)ctx.body=res}catch(err){ctx.body=err}})functionsetQuestUrl(url){if(/^\/t/.test(url)){return'host1'+url.replace(/^\/t/,'')}if(/^\/xt/.test(url)){返回'host2'+url.replace(/^\/xt/,'')}}module.exports=routerrouter.get('/*',async(ctx,next)=>{})koarouting'/*'为通配符,匹配所有的get请求;next方法调用意味着进入下一个中间件;ctx请求上下文,ctx.request.bodypost请求参数koa中间件原理洋葱圈模型:constKoa=require('koa2');constapp=newKoa();//loggerapp.use(async(ctx,next)=>{console.log('第一层洋葱-开始')awaitnext();constrt=ctx.response.get('X-Response-Time');console.log(`${ctx.method}${ctx.url}-${rt}`);console.log('第一层洋葱-结束')});//x-response-timeapp.use(async(ctx,next)=>{console.log('Secondonion-start')conststart=Date.now();awaitnext();constms=Date.now()-start;ctx.set('X-Response-Time',`${ms}ms`);console.log('Secondonion-end')});//responseapp.use(asyncctx=>{console.log('第三层洋葱-开始')ctx.body='HelloWorld';console.log('第三层洋葱-结束')});app.listen(8000);//输出第一层洋葱-开始第二层洋葱-开始第三层洋葱-开始第三层洋葱-结束第二层洋葱-结束第一层洋葱-结束setQuestUrl这个方法主要是访问前端路径根据一级转发到不同的host例如:/t->host13.3转发请求httpReque本例中的st.js主要是代理访问和携带cookie,const.js硬编码携带cookieletkoa2Req=require('koa2-request')letconstConfig=require('./const')letiToken=constConfig。iTokenletkoaRequest=asyncfunction(url,method,ctx){letoptions={方法:方法,uri:url,超时:120000,正文:ctx?{...ctx.request.body}:null,headers:{},json:true//自动将正文字符串化为JSON}options.headers['Cookie']=`i-token=${iToken}`//Setcookieletres=awaitkoa2Req(options)returnres.body}//node-monasyncfunctiongetTestToken(){if(!constConfig.iToken){leturl=`http://xt.eqxiu.com/tui/app/radar/test/getToken?companyId=${constConfig.companyId}&staffId=${constConfig.staffId}`try{letres=awaitkoaRequest(url,'GET')iToken=res.objconsole.log('令牌已经得到:'+iToken)}catch(e){console.log(e)}}}getTestToken()module.exports=koaRequest3.4最后设置端口等constapp=require('./app')//constcreateWebsocket=require('./websocket')constserver=require('http').createServer(app.callback())server.setTimeout(2*60*1000)//Settimeoutconst{PORT=3000}=process.envserver.listen(PORT,()=>{console.log(`Listeningonport${PORT}`)})3.5本地开发,热重启安装nodemonyarn添加nodemon设置忽略监控nodemon.josn节点项目根目录{"ignore":["node_modules/*"]//忽略node_modules下的文件修改监控}package.josn通过npmrunserver{"dependencies":{"koa":"^2.8.1","koa-bodyparser":"^4.2.1","koa-router":"^7.4.0","koa2-request":"^1.0.4","nodemon":“^1.19.1”},“脚本”:{“服务器”:“nodemonindex.js”}}
