zoukankan      html  css  js  c++  java
  • npm模块之http-proxy-middleware使用教程(译)

    单线程node.js代理中间件,用于连接,快速和浏览器同步

    Node.js代理简单。 轻松配置代理中间件连接,快速,浏览器同步等。

    由流行的Nodejitsu http代理提供。

    TL;DR

    代理/ api请求到http://www.example.org

    1 var express = require('express');
    2 var proxy = require('http-proxy-middleware');
    3 
    4 var app = express();
    5 
    6 app.use('/api', proxy({target: 'http://www.example.org', changeOrigin: true}));
    7 app.listen(3000);

    可以使用所有http-proxy选项,以及一些额外的http-proxy-middleware选项。

    提示:将基于名称的虚拟托管网站的选项changeOrigin设置为true

    内容列表

    • 安装
    • 核心概念
    • 举个栗子
    • 上下文匹配
    • 选项 
      • http-proxy-middleware选项
      • http-proxy事件
      • http-proxy选项
    • 速记 
      • app.use(path, proxy)
    • WebSocket 
      • 外部Websocket升级
    • 工作示例
    • Recipes
    • 兼容的服务器
    • 测试
    • 更新日志
    • License

    Install

    $ npm install --save-dev http-proxy-middleware

    proxy([context,] config)

    var proxy = require('http-proxy-middleware');
    
    var apiProxy = proxy('/api', {target: 'http://www.example.org'});
    //                   \____/   \_____________________________/ 
    //                     |                    | 
    //                   context             options 
    
    // 'apiProxy' is now ready to be used as middleware in a server. 
    • context:确定应将哪些请求代理到目标主机。 (更多关于上下文匹配)
    • options.target:目标主机到代理。 (协议+主机)

    http-proxy-middleware配置选项的完整列表)

    proxy(uri [, config])

    // shorthand syntax for the example above: 
    var apiProxy = proxy('http://www.example.org/api');

    更多关于速记配置。


    举个栗子

    使用express服务器的示例。

    // include dependencies 
    var express = require('express');
    var proxy = require('http-proxy-middleware');
    
    // proxy middleware options 
    var options = {
            target: 'http://www.example.org', // target host 
            changeOrigin: true,               // needed for virtual hosted sites 
            ws: true,                         // proxy websockets 
            pathRewrite: {
                '^/api/old-path' : '/api/new-path',     // rewrite path 
                '^/api/remove/path' : '/path'           // remove base path 
            },
            router: {
                // when request.headers.host == 'dev.localhost:3000', 
                // override target 'http://www.example.org' to 'http://localhost:8000' 
                'dev.localhost:3000' : 'http://localhost:8000'
            }
        };
    
    // create the proxy (without context) 
    var exampleProxy = proxy(options);
    
    // mount `exampleProxy` in web server 
    var app = express();
        app.use('/api', exampleProxy);
        app.listen(3000);

    Context matching

    提供一种替代方式来决定哪些请求应该被代理;如果您无法使用服务器的路径参数来装载代理,或者需要更多的灵活性。

    RFC 3986路径用于上下文匹配。

             foo://example.com:8042/over/there?name=ferret#nose
             \_/   \______________/\_________/ \_________/ \__/
              |           |            |            |        |
           scheme     authority       path        query   fragment
    • 路径匹配 
      • proxy({...}) - 匹配任意路径,所有的请求都会被代理。
      • proxy('/', {...})-匹配任意路径,所有的请求都会被代理。
      • proxy('/api', {...})-匹配所有以/api开始的路径。
    • 多重路径匹配 
      • proxy(['/api', '/ajax', '/someotherpath'], {...})
    • 通配符路径匹配 
      对于细粒度控制,您可以使用通配符匹配。通过micromatch进行全局模式匹配。访问micromatchglob更多globbing示例。

      • proxy('**', {...}) 匹配任意路径,所有的请求都会被代理。
      • proxy('**/*.html', {...}) 匹配所有以.html结尾的任意路径。
      • proxy('/*.html', {...}) 直接匹配绝对路径下的路径。
      • proxy('/api/**/*.html', {...})匹配在/api路径下以.html结尾的请求。
      • proxy(['/api/**', '/ajax/**'], {...})组合多重路由模式。
      • proxy(['/api/**', '!**/bad.json'], {...})排除匹配。
    • 自定义匹配 
      为了完全控制,您可以提供一个自定义函数来确定哪些请求应该被代理。
    var filter = function (pathname, req) {
        return (pathname.match('^/api') && req.method === 'GET');
    };
    
    var apiProxy = proxy(filter, {target: 'http://www.example.org'})

    选项

    http-proxy-middleware选项

    • option.pathRewrite:对象/函数,重写目标的url路径。对象键将被用作RegExp来匹配路径。

       1 // rewrite path 
       2 pathRewrite: {'^/old/api' : '/new/api'}
       3 
       4 // remove path 
       5 pathRewrite: {'^/remove/api' : ''}
       6 
       7 // add base path 
       8 pathRewrite: {'^/' : '/basepath/'}
       9 
      10 // custom rewriting 
      11 pathRewrite: function (path, req) { return path.replace('/api', '/base/api') }
          option.router:对象/函数,重新定位特定请求的

    option.target

     1 // Use `host` and/or `path` to match requests. First match will be used. 
     2 // The order of the configuration matters. 
     3 router: {
     4     'integration.localhost:3000' : 'http://localhost:8001',  // host only 
     5     'staging.localhost:3000'     : 'http://localhost:8002',  // host only 
     6     'localhost:3000/api'         : 'http://localhost:8003',  // host + path 
     7     '/rest'                      : 'http://localhost:8004'   // path only 
     8 }
     9 
    10 // Custom router function 
    11 router: function(req) {
    12     return 'http://localhost:8004';
    13 }


          option.logLevel:字符串, [‘debug’, ‘info’, ‘warn’, ‘error’, ‘silent’]. 默认:

    'info'

          • option.logProvider:函数,修改或者替换日志服务。默认:'console'

             1 // simple replace 
             2 function logProvider(provider) {
             3     // replace the default console log provider. 
             4     return require('winston');
             5 }
             6 // verbose replacement 
             7 function logProvider(provider) {
             8     var logger = new (require('winston').Logger)();
             9 
            10     var myCustomProvider = {
            11         log: logger.log,
            12         debug: logger.debug,
            13         info: logger.info,
            14         warn: logger.warn,
            15         error: logger.error
            16     }
            17     return myCustomProvider;
            18 }
          • 1(已弃用)option.proxyHost:用

    option.changeOrigin = true

          代替。
          • (已弃用)option.proxyTable:用option.router代替。

          • http-proxy 事件

    订阅http-proxy事件

          • option.onError:函数,订阅http-proxyerror事件以进行自定义错误处理。

            1 function onError(err, req, res) {
            2     res.writeHead(500, {
            3         'Content-Type': 'text/plain'
            4     });
            5     res.end('Something went wrong. And we are reporting a custom error message.');
            6 }
          • option.onProxyRes:函数,订阅

    http-proxy

    proxyRes

          事件。
     1 function onProxyRes(proxyRes, req, res) {
     2     proxyRes.headers['x-added'] = 'foobar';     // add new header to response 
     3     delete proxyRes.headers['x-removed'];       // remove header from response 
     4 }
     5 
     6 
     7 option.onProxyReq:函数,订阅http-proxy的proxyReq事件。
     8 function onProxyReq(proxyReq, req, res) {
     9     // add custom header to request 
    10     proxyReq.setHeader('x-added', 'foobar');
    11     // or log the req 
    12 }
    13 option.onProxyReqWs:函数,订阅http-proxy的proxyReqWs事件。
    14 function onProxyReqWs(proxyReq, req, socket, options, head) {
    15     // add custom header 
    16     proxyReq.setHeader('X-Special-Proxy-Header', 'foobar');
    17 }
          option.onOpen:函数,订阅

    http-proxy

          的 

    open

        事件。
    1 function onOpen(proxySocket) {
    2     // listen for messages coming FROM the target here 
    3     proxySocket.on('data', hybiParseAndLogMessage);
    4 }
    • option.onClose:函数,订阅http-proxy 的close事件。

      1 function onClose(res, socket, head) {
      2     // view disconnected websocket connections 
      3     console.log('Client disconnected');
      4 }

    http-proxy选项

    底层http-proxy库提供以下选项。

    • option.target:url字符串将与url模块解析
    • option.forward:url字符串将与url模块解析
    • option.target:传递给http(s)请求的对象(参阅Node https代理和http代理对象)
    • option.ssl:传递给https.createServer()的对象
    • option.ws:true / false,如果你想要代理websockets
    • option.xfwd:true / false,添加x-forward请求头
    • option.secure:true / false,如果你想要验证SSL证书
    • option.toProxy:true / false,将绝对URL作为path(对代理使用代理时很有用)
    • option.prependPath:true / false,默认:true-指定是否要将目标的路径预置到代理路径
    • option.ignorePath:true / false,默认:false-指定是否要忽略传入请求的代理路径(注意:如果需要,您将必须附加/手动)。
    • option.localAddress:用于传出连接的本地接口字符串
    • option.changeOrigin:true / false,默认值:false - 将主机头的源更改为目标URL
    • option.auth:基本认证,即“用户:密码”来计算授权头。
    • option.hostRewrite:重写(301/302/307/308)重定向的位置主机名。
    • option.autoRewrite:根据请求的主机/端口重写(301/302/307/308)重定向的位置主机/端口。默认值:false。
    • option.protocolRewrite:重写位置协议(301/302/307/308)重定向到’http’或’https’。默认值:null。
    • option.cookieDomainRewrite:重写set-cookie标头的域。可能的值: 
      false(默认):禁止重写cookie 
      - 字符串:新域名,比如说cookieDomainRewrite:"new.domain"。使用cookieDomainRewrite:""删除域名。 
      - 对象:域名到新域名的映射,用”*”匹配所有域名。 
      举个栗子:保持一个域名不变,重写一个域名并且删除其他的: 

      cookieDomainRewrite: { 
      "unchanged.domain": "unchanged.domain", 
      "old.domain": "new.domain", 
      "*": "" 

    • option.headers:对象,添加请求头。(比如:{host:'www.example.org'}
    • option.proxyTimeout:超时时间(毫秒)当代理接收不到目标服务器的返回

    速记

    当不需要详细配置时,请使用简写语法。当使用速记时,上下文和option.target将被自动配置。如果需要,仍然可以使用选项。

     1 proxy('http://www.example.org:8000/api');
     2 // proxy('/api', {target: 'http://www.example.org:8000'}); 
     3 
     4 
     5 proxy('http://www.example.org:8000/api/books/*/**.json');
     6 // proxy('/api/books/*/**.json', {target: 'http://www.example.org:8000'}); 
     7 
     8 
     9 proxy('http://www.example.org:8000/api', {changeOrigin:true});
    10 // proxy('/api', {target: 'http://www.example.org:8000', changeOrigin: true}); 
    11  

    app.use(path, proxy)

    如果要使用服务器的app.usepath参数匹配请求;创建并装载不带http-proxy-middleware`上下文参数的代理:

    app.use('/api', proxy({target:'http://www.example.org', changeOrigin:true}));

    app.use文档


    Websocket

    1 // verbose api 
    2 proxy('/', {target:'http://echo.websocket.org', ws:true});
    3 
    4 // shorthand 
    5 proxy('http://echo.websocket.org', {ws:true});
    6 
    7 // shorter shorthand 
    8 proxy('ws://echo.websocket.org');
     

    外部WebSocket升级

    在以前的WebSocket示例中,http代理中间件依赖于初始http请求以便侦听http升级事件。如果需要在没有初始http请求的情况下代理WebSockets,则可以手动预订服务器的http升级事件。

    1 var wsProxy = proxy('ws://echo.websocket.org', {changeOrigin:true});
    2 
    3 var app = express();
    4     app.use(wsProxy);
    5 
    6 var server = app.listen(3000);
    7     server.on('upgrade', wsProxy.upgrade);  // <-- subscribe to http 'upgrade' 
  • 相关阅读:
    Redis缓存穿透、缓存雪崩、redis并发问题 并发竞争key的解决方案 (阿里)
    CAP原则 (阿里)
    分布式系统一致性问题解决实战(阿里) 异步解耦+消息队列可作为分布式系统满足最终一致性的优秀方案
    高并发&高可用系统的常见应对策略 秒杀等-(阿里)
    Redis的内存回收策略和内存上限(阿里)
    如何保证MQ的顺序性?比如Kafka
    spring的controller默认是单例还是多例
    HashMap线程不安全的体现
    TCP的三次握手与四次挥手
    常见排序算法及对应的时间复杂度和空间复杂度
  • 原文地址:https://www.cnblogs.com/cangqinglang/p/9050500.html
Copyright © 2011-2022 走看看