zoukankan      html  css  js  c++  java
  • Express 框架以及与http-proxy-middleware整合实现代理

    1.Express的简单使用

    1.简介

    Express 是一个简洁而灵活的 node.js Web应用框架, 提供了一系列强大特性帮助你创建各种 Web 应用,和丰富的 HTTP 工具。

    使用 Express 可以快速地搭建一个完整功能的网站。

    Express 框架核心特性:

    • 可以设置中间件来响应 HTTP 请求。

    • 定义了路由表用于执行不同的 HTTP 请求动作。

    • 可以通过向模板传递参数来动态渲染 HTML 页面。

    2.安装

    cnpm install --save-dev express

    3.运行第一个实例

    var express = require('express');
    var app = express();
     
    app.get('/', function (req, res) {
       res.send('Hello World');
    })
     
    var server = app.listen(8081, function () {
     
      var host = server.address().address
      var port = server.address().port
     
      console.log("应用实例,访问地址为 http://%s:%s", host, port)
     
    })

    运行:

    C:UsersAdministratorDesktop
    odejsTest>node ./nodeHttp.js
    应用实例,访问地址为 http://:::8081

    浏览器访问:

     4.请求和响应

    Express 应用使用回调函数的参数: request 和 response 对象来处理请求和响应的数据。

    app.get('/', function (req, res) {
       // --
    })

    request 和 response 对象的具体介绍:

    Request 对象 - request 对象表示 HTTP 请求,包含了请求查询字符串,参数,内容,HTTP 头部等属性。常见属性有:

    1. req.app:当callback为外部文件时,用req.app访问express的实例
    2. req.baseUrl:获取路由当前安装的URL路径
    3. req.body / req.cookies:获得「请求主体」/ Cookies
    4. req.fresh / req.stale:判断请求是否还「新鲜」
    5. req.hostname / req.ip:获取主机名和IP地址
    6. req.originalUrl:获取原始请求URL
    7. req.params:获取路由的parameters
    8. req.path:获取请求路径
    9. req.protocol:获取协议类型
    10. req.query:获取URL的查询参数串
    11. req.route:获取当前匹配的路由
    12. req.subdomains:获取子域名
    13. req.accepts():检查可接受的请求的文档类型
    14. req.acceptsCharsets / req.acceptsEncodings / req.acceptsLanguages:返回指定字符集的第一个可接受字符编码
    15. req.get():获取指定的HTTP请求头
    16. req.is():判断请求头Content-Type的MIME类型

    Response 对象 - response 对象表示 HTTP 响应,即在接收到请求时向客户端发送的 HTTP 响应数据。常见属性有:

    1. res.app:同req.app一样
    2. res.append():追加指定HTTP头
    3. res.set()在res.append()后将重置之前设置的头
    4. res.cookie(name,value [,option]):设置Cookie
    5. opition: domain / expires / httpOnly / maxAge / path / secure / signed
    6. res.clearCookie():清除Cookie
    7. res.download():传送指定路径的文件
    8. res.get():返回指定的HTTP头
    9. res.json():传送JSON响应
    10. res.jsonp():传送JSONP响应
    11. res.location():只设置响应的Location HTTP头,不设置状态码或者close response
    12. res.redirect():设置响应的Location HTTP头,并且设置状态码302
    13. res.render(view,[locals],callback):渲染一个view,同时向callback传递渲染后的字符串,如果在渲染过程中有错误发生next(err)将会被自动调用。callback将会被传入一个可能发生的错误以及渲染后的页面,这样就不会自动输出了。
    14. res.send():传送HTTP响应
    15. res.sendFile(path [,options] [,fn]):传送指定路径的文件 -会自动根据文件extension设定Content-Type
    16. res.set():设置HTTP头,传入object可以一次设置多个头
    17. res.status():设置HTTP状态码
    18. res.type():设置Content-Type的MIME类型

    5.静态文件

    Express 提供了内置的中间件 express.static 来设置静态文件如:图片, CSS, JavaScript 等。

    你可以使用 express.static 中间件来设置静态文件路径。例如,如果你将图片, CSS, JavaScript 文件放在 public 目录下,你可以这么写:

    app.use('/public', express.static('public'));

    例如:当前目录/public/test.html 内容如下:

    <html>
        <head></head>
        <script src="https://code.jquery.com/jquery-3.1.1.min.js"></script>
        <body>
            <h1>test</h1>
        </body>
    </html>

    nodejs源码如下:

    var express = require('express');
    var app = express();
     
    app.use('/public', express.static('public'));
     
    app.get('/', function (req, res) {
       res.send('Hello World');
    })
     
    var server = app.listen(8081, function () {
     
      var host = server.address().address
      var port = server.address().port
     
      console.log("应用实例,访问地址为 http://%s:%s", host, port)
     
    })

    运行访问测试:

    6.Cookie 管理

    我们可以使用中间件向 Node.js 服务器发送 cookie 信息,以下代码输出了客户端发送的 cookie 信息:

    var express      = require('express')
    var cookieParser = require('cookie-parser')
    var util = require('util');
     
    var app = express()
    app.use(cookieParser())
     
    app.get('/', function(req, res) {
        console.log("Cookies: " + util.inspect(req.cookies));
    })
     
    app.listen(8081)

      缺少模块需要安装对应的模块。

    补充:app.use([path,], function [, function...]) 挂载中间件方法到路径上。如果路径未指定,那么默认为"/"。

      一个路由将匹配任何路径如果这个路径以这个路由设置路径后紧跟着"/"。比如:app.use('/appale', ...)将匹配"/apple","/apple/images","/apple/images/news"等。

    中间件方法是顺序处理的,所以中间件包含的顺序是很重要的。例如:

    var express      = require('express')
     
    var app = express()
    // this middleware will not allow the request to  go beyond it
    app.use(function(req, res, next) {
        res.send('Hello World');
    });
    
    // this middleware will never reach this route
    app.use('/', function(req, res) {
        res.send('Welcome');
    });
     
    app.listen(8081)

    访问测试:

    参考:https://www.runoob.com/w3cnote/express-4-x-api.html

    2.http-proxy-middleware实现代理

    参考:https://github.com/chimurai/http-proxy-middleware#proxycontext-config

    1.安装模块

    cnpm install --save-dev http-proxy-middleware

    2.简单的代理

    后台springboot代码:

    package cn.qs.controller.test;
    
    import java.util.LinkedHashMap;
    import java.util.Map;
    
    import org.apache.commons.collections.MapUtils;
    import org.springframework.web.bind.annotation.GetMapping;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.RequestParam;
    import org.springframework.web.bind.annotation.RestController;
    
    @RequestMapping("/test")
    @RestController
    public class TestController {
        @GetMapping("/get")
        public Map<String, Object> get(@RequestParam Map<String, Object> condition, HttpServletRequest request) {
            Enumeration<String> headerNames = request.getHeaderNames();
            while (headerNames.hasMoreElements()) {
                String header = (String) headerNames.nextElement();
                String value = request.getHeader(header);
                System.out.println(header + "	" + value);
            }
    
            if (MapUtils.isEmpty(condition)) {
                condition = new LinkedHashMap<>();
                condition.put("param", null);
            }
    
            return condition;
        }
    
    }

    直接访问后台:

    代理代码:

    var express = require('express');
    var proxy = require('http-proxy-middleware');
    
    var app = express();
    
    app.use(
      '/test',
      proxy({ target: 'http://localhost:8088' })
    );
    
    var server = app.listen(80, function () {
     
      var host = server.address().address
      var port = server.address().port
     
      console.log("应用实例,访问地址为 http://%s:%s", host, port)
    });

    启动:

    C:UsersAdministratorDesktop
    odejsTest>node ./nodeHttp.js
    [HPM] Proxy created: /  -> http://localhost:8088
    应用实例,访问地址为 http://:::80

    访问结果:

     后台控制台日志:

    cookie JSESSIONID=78CB07C2CD30020D4EB504C1E3659EAD
    accept-language    zh-CN,zh;q=0.9
    accept-encoding    gzip, deflate, br
    sec-fetch-mode    navigate
    sec-fetch-site    none
    accept    text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3
    sec-fetch-user    ?1
    user-agent    Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.108 Safari/537.36
    upgrade-insecure-requests    1
    cache-control    no-cache
    pragma    no-cache
    connection    close
    host    localhost

    3.代理进行处理

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

    解释:

    (1)changeOrigin为true是改变origin参数到目标链接中

    (2)ws为true是允许代理websocket请求

    (3)pathRewrite是重写路径,可以对路径进行增加、修改、删除等操作。

    (4)router是根据域名以及端口重新定义target。

    上面路径最后的结果如下:(我们可以在hosts配置虚拟域名进行测试)

    http://localhost:3000/api/get.html  ====   http://localhost:8088/test/get.html
    http://localhost:3000/api/server/test/get.html  ====   http://localhost:8088/test/get.html
    http://a.com:3000/api/get.html  ====   http://b.com:8088/test/get.html
    http://a.com:3000/api/server/test/get.html  ====   http://b.com:8088/test/get.html

    测试:

     后台控制台代码:

    cookie    cookie1=value1
    accept-language    zh-CN,zh;q=0.9
    accept-encoding    gzip, deflate
    accept    text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3
    user-agent    Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.108 Safari/537.36
    upgrade-insecure-requests    1
    connection    close
    host    b.com:8088
  • 相关阅读:
    UIControl IOS控件编程 及UITextField的讲解
    ViewPager实现页面切换
    HDU 3788 和九度OJ 1006测试数据是不一样的
    的基本原理的面向对象的--------单个程序员必须查看
    hdu1796 How many integers can you find
    Android数据加载和Json解析——蓝本
    设计管理员表;webservice用于网络安全的高端内提供服务的
    how tomcat works 札记(两)----------一个简单的servlet集装箱
    新秀学习Hibernate——一个简单的例子
    在cocos2d-x在CCTableView使用控制
  • 原文地址:https://www.cnblogs.com/qlqwjy/p/12012783.html
Copyright © 2011-2022 走看看