关闭

node.js代理访问

时间: 2019-08-18阅读: 972标签: 代理

1. 场景

本地开发,代理访问,防止跨域(一般通过webpack配置代理即可),特殊情况如携带一些自定义的登录cookie则需要通过自己写node,作为一种server中间层,单线程异步可以缓解服务器压力。长链接websocket通常使用node搭建


2. 技术框架

node - koa2 体量小,轻便易用。

路由koa-router koa配套路由,中间件支持async

koa2-request 基于async对 request的封装,这里本人git上找的,可靠性带考量,若基于生产环境建议使用request自行封装

koa-bodyparser 请求参数解析格式化-中间件


3. 上代码

3.1 创建应用 app.js
const Koa = require('koa')
const bodyParser = require('koa-bodyparser')
// 路由
const router = require('./router')
const app = new Koa()

app.use(
  bodyParser({
      // 返回的对象是一个键值对,当extended为false的时候,键值对中的值就为'String'或'Array'形式,为true的时候,则可为任何数据类型。
    extended: true 
  })
)
3.2 允许跨域 app.js
app.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'
  )
  await next()
})
3.2 使用路由
// app.js
app.use(router.routes())

// router.js
const Router = require('koa-router')
let koaRequest = require('./httpRequest')
const router = new Router()

router.get('/*', async (ctx, next) => {
  const url = setQuestUrl(ctx.url)
  try {
    let res = await koaRequest(url, 'GET', ctx)
    ctx.body = res
  } catch (err) {
    ctx.body = err
  }
})

router.post('/*', async (ctx, next) => {
  const url = setQuestUrl(ctx.url)
  try {
    let res = await koaRequest(url, 'POST', ctx)
    ctx.body = res
  } catch (err) {
    ctx.body = err
  }
})

function setQuestUrl(url) {
  if (/^\/t/.test(url)) {
    return 'host1'+ url.replace(/^\/t/, '')
  }
  if (/^\/xt/.test(url)) {
    return 'host2' + url.replace(/^\/xt/, '')
  }
}

module.exports = router

router.get('/*', async (ctx, next) => {}) koa路由 ‘/*’ 为通配符,匹配所有get请求;next方法调用表示进入下一个中间件;

ctx请求上下文,ctx.request.body post请求参数

koa的中间件原理 洋葱圈模型:


const Koa = require('koa2');
const app = new Koa();

// logger
app.use(async (ctx, next) => {
  console.log('第一层洋葱 - 开始')
  await next();
  const rt = ctx.response.get('X-Response-Time');
  console.log(`${ctx.method} ${ctx.url} - ${rt}`);
  console.log('第一层洋葱 - 结束')
});

// x-response-time
app.use(async (ctx, next) => {
  console.log('第二层洋葱 - 开始')
  const start = Date.now();
  await next();
  const ms = Date.now() - start;
  ctx.set('X-Response-Time', `${ms}ms`);
  console.log('第二层洋葱 - 结束')
});

// response
app.use(async ctx => {
  console.log('第三层洋葱 - 开始')
  ctx.body = 'Hello World';
  console.log('第三层洋葱 - 结束')
});

app.listen(8000);


// 输出

第一层洋葱 - 开始
第二层洋葱 - 开始
第三层洋葱 - 开始

第三层洋葱 - 结束
第二层洋葱 - 结束
第一层洋葱 - 结束

setQuestUrl 此方法主要是将前端访问的路径,根据第一级转发到不同的host上

例如: /t -> host1

3.3 转发请求 httpRequest.js

本例主要为了代理访问并携带Cookie, const.js 为写死的要携带的cookie

let koa2Req = require('koa2-request')

let constConfig = require('./const')

let iToken = constConfig.iToken

let koaRequest = async function(url, method, ctx) {
  let options = {
    method: method,
    uri: url,
    timeout: 120000,
    body: ctx
      ? {
          ...ctx.request.body
        }
      : null,
    headers: {},
    json: true // Automatically stringifies the body to JSON
  }
  options.headers['Cookie'] = `i-token=${iToken}` //设置cookie
  let res = await koa2Req(options)

  return res.body
}

// node-mon

async function getTestToken() {
  if (!constConfig.iToken) {
    let url = `http://xt.eqxiu.com/tui/app/radar/test/getToken?companyId=${constConfig.companyId}&staffId=${constConfig.staffId}`
    try {
      let res = await koaRequest(url, 'GET')
      iToken = res.obj
      console.log('token已拿到:' + iToken)
    } catch (e) {
      console.log(e)
    }
  }
}

getTestToken()

module.exports = koaRequest
3.4 最后设置端口等

const app = require('./app')
//const createWebsocket =  require('./websocket')

const server = require('http').createServer(app.callback())

server.setTimeout(2 * 60 * 1000) //设置超时时间

const { PORT = 3000 } = process.env

server.listen(PORT, () => {
  console.log(`Listening on port ${PORT}`)
})
3.5 本地开发,热重启

安装 nodemon

yarn add nodemon

设置忽略监听

nodemon.josn node项目根目录下

{
  "ignore": ["node_modules/*"] //忽略node_modules下文件修改的监听
}

package.josn

通过npm run server启动

{
  "dependencies": {
    "koa": "^2.8.1",
    "koa-bodyparser": "^4.2.1",
    "koa-router": "^7.4.0",
    "koa2-request": "^1.0.4",
    "nodemon": "^1.19.1"
  },
  "scripts": {
    "server": "nodemon index.js"
  }
}


站长推荐

1.云服务推荐: 国内主流云服务商,各类云产品的最新活动,优惠券领取。地址:阿里云腾讯云华为云

2.广告联盟: 整理了目前主流的广告联盟平台,如果你有流量,可以作为参考选择适合你的平台点击进入

链接: http://www.fly63.com/article/detial/5382

关闭

.Net Core/Framework之Nginx反向代理后获取客户端IP等数据探索

公司项目最近出现获取访问域名、端口、IP错误现象,通过排查发现, 之前项目一直通过Nginx自定义Headers信息来获取,但最近运维人员失误操作造成自定义Header信息丢失,造成项目拿不到对应的数据。

vue proxy代理跨域

changeOrigin的属性值为一个布尔值,如果设置为true,那么本地会虚拟一个NODE服务端接收你的请求并代你发送该请求(中间件)。[本质上是本地开了一个服务器dev-server,所有的请求都通过这里转发出去。]

ES6中的代理(Proxy)和反射(Reflection)

调用 new Proxy() 可常见代替其它目标 (target) 对象的代理,它虚拟化了目标,所以二者看起来功能一致。代理可拦截JS引擎内部目标的底层对象操作,这些底层操作被拦截后会触发响应特定操作的陷阱函数。

如何使用Proxy 来代理Js中的类?

Proxy 对象(Proxy)是 ES6 的一个非常酷却鲜为人知的特性。虽然这个特性存在已久,但是我还是想在本文中对其稍作解释,并用一个例子说明一下它的用法。

Proxy代理

在一个系统中,总要存储一些数据,对于这些数据,可能有一些是希望我们访问的,但是总有一些是中重要的,不希望我们访问的,希望保护起来,因此ES6新增了代理,在目标对象前架设个拦截层

反向代理和内网穿透

反向代理看上去看深奥,其实不然,只是因为汉语言文化的差异导致它看上去深奥。一般反派感觉都比较厉害和神秘。要理解反向代理,我们就不得不说一下正向代理。正向代理代理的对象是客户端;反向代理代理的对象是服务端

什么是在线代理ip网页代理

当我们需要大量IP进行快节奏完成业绩的时候,很多人都会想到去IP代理服务商那里购买IP代理,所以我相信很多人对于IP代理这个词已经有一定的认识了,那么还有一个词叫做:在线代理ip网页代理

Nginx反向代理之动静分离

我们已经知道了什么是正向代理与反向代理,这次我们就讲一下Nginx的动静分离的案例,其实质运用的就是反向代理,专门用一台服务器代理服务器上的图片资源。

JavaScript代理的惊人威力

今天我们要学习的是ECMAScript 6的代理。我们将在本文中涉及以下主题。什么是代理?代理人在行动,谁使用代理,使用案例和实例,资源

node怎么做反向代理?

在实际工程开发中,会有前后端分离的需求。使用node.js反向代理的目的:实现前后端分离,前端减少路径请求的所需的路由文件。

点击更多...

内容以共享、参考、研究为目的,不存在任何商业目的。其版权属原作者所有,如有侵权或违规,请与小编联系!情况属实本人将予以删除!