zoukankan      html  css  js  c++  java
  • node anyproxy ssi简易支持

    在项目中,ssi include是一个比较常用的功能,这样我们就可以通过web服务器的支持,将公用的html提取出来,改一个文件就会修改全部内容

    但是这也带来了问题,在开发的时候没办法的刷新查看,需要提交测试服务器才可以,当然也可以通过在本地通过nginx服务器做到这些。

    现在我们有了nodejs,github上面也有很多好的本地代理项目,anyproxy,whistle,livepool...

    平时主要用 whistle 操作配置上面都很简单,通过简单配置也可以实现很多功能

    livepool,装了下,看着想fiddler,操作起来主要感觉主要是界面操作,就没怎么用

    anyproxy,这个是需要自己写js,定义规则的,灵活性好些,但是写代码总归麻烦的

    今天通过对比,感觉anyproxy实现node ssi功能比较简单些,其实也很简单,详见代码 时间有限,都是通过同步api写的,略有遗憾

    /*
      read the following wiki before using rule file
      https://github.com/alibaba/anyproxy/wiki/What-is-rule-file-and-how-to-write-one
    */
    "use strict";
    const fs = require('fs');
    const url = require("url");
    const path = require("path");
    var _getNewFPath = function (newUrl) {
        var urlObject = url.parse(newUrl, true);
        return path.join(this.hostFilePath, urlObject.pathname);
    }
    const config = [
        {
            urlInclude: 'http://mall.snail.com/pickCard/',
            hostFilePath: 'D:/snailshop/mall-snail-com/mall',
            ssi: true,
            getNewFPath: function (newUrl) {
                var urlObject = url.parse(newUrl, true);
                if (newUrl.indexOf('http://mall.snail.com/includes/') != -1) {
                    return path.join('D:/snailshop/mall-snail-com/', urlObject.pathname);
                }
                return path.join(this.hostFilePath, urlObject.pathname);
            }
        },
        {
            urlInclude: 'http://static.snail.com/',
            hostFilePath: 'D:/snailshop/mall-snail-com/public',
            getNewFPath: _getNewFPath
        }
    ];
    
    var map = {};
    var ssiReadFile = function (reqUrl, ssiOpt) {
        map = {};
        return _ssiReadFile(reqUrl, ssiOpt, [])
    };
    var _ssiReadFile = function (reqUrl, ssiOpt, accessPath) {
        var readFPath = ssiOpt.getNewFPath(reqUrl);
        console.log('_ssiReadFile1', readFPath)
        var stat = fs.statSync(readFPath);
        var content;
        if (stat && stat.isFile()) {
            content = fs.readFileSync(readFPath, {encoding: 'utf8'});
            var match = content.match(/<!--#s*includes+file=(["']).+?1s*-->/g);
            console.log('_ssiReadFile2', match);
            if (match) {
                match.forEach((m) => {
                    var fileStr = m.match(/<!--#s*includes+file=(["'])(.+?)1s*-->/)[2];
                    var newUrl = url.resolve(reqUrl, fileStr);
                    if (accessPath.indexOf(newUrl) != -1) {//存在循环
                        map[newUrl] = "loop " + newUrl +' in [ '+ accessPath.join() + ']';
                    } else if (!map[newUrl]) {
                        var _access = accessPath.slice(0);
                        _access.push(newUrl);
                        map[newUrl] = _ssiReadFile(newUrl, ssiOpt, _access);
                    }
                })
                content = content.replace(/<!--#s*includes+file=(["'])(.+?)1s*-->/g, function (a, b, fileStr) {
                    var newUrl = url.resolve(reqUrl, fileStr);
                    return map[newUrl];
                });
            }
        } else {
            content = 'not find file ' + readFPath;
        }
        return content;
    }
    
    module.exports = {
        summary: function(){
            return "mall 项目";
        },
        replaceRequestOption : function(req, option){
            var host = option.headers.host;
            if(host == "mall.snail.com" || host == "static.snail.com" || host == "m.mall.snail.com"){
                option.hostname = "10.13.0.206";
                option.port = "80";
            } else if (host == "mobile.snail.com" || host == "m.mobile.snail.com"){
                option.hostname = "10.13.0.205";
                option.port = "80";
            }  else if (host == "cmsv3.snailsite.com"){
                option.hostname = "10.110.1.3";
                option.port = "80";
            } 
            
            return option;
        },
        shouldInterceptHttpsReq :function(req){
            return false;
        },
        shouldUseLocalResponse : function(req, reqBody){
            var reqUrl = req.url;
            var urlObject = url.parse(reqUrl, true);
            for (var i = 0, len = config.length; i < len ; i++) {
                let opt = config[i];
                if (reqUrl.indexOf(opt.urlInclude) != -1) {
                    let newPath = path.join(opt.hostFilePath, urlObject.pathname);
                    let stat = fs.statSync(newPath);
                    if (stat && stat.isFile()) {
                        console.log('shouldUseLocalResponse', newPath)
                        req.ssi = opt.ssi || false;
                        req.ssiOpt = opt;
                        return true;
                    }
                }
            }
            return false;
        },
    
        dealLocalResponse : function(req, reqBody, callback){
            console.log('dealLocalResponse', req.ssi);
            if (req.ssi) {
                callback(200, {"content-type": "text/html"}, ssiReadFile(req.url, req.ssiOpt));
            } else {
                callback(200, {}, fs.readFileSync(req.ssiOpt.getNewFPath(req.url)));
            }
            delete req.ssiOpt;
            delete req.ssi;
        }
    };
  • 相关阅读:
    如何查看python的当前版本号
    Android数据库程序开发必备工具SqliteDev 狼人:
    Android四种Activity的加载模式 狼人:
    20+ 个很棒的 jQuery 文件上传插件或教程(此文值得“推荐”和“收藏”) 狼人:
    艾伟:10分钟去除天天团购系统版权 狼人:
    WIN7,server2008 IIS 伪静态 不能显示特殊图片 加号 减号 “+”,""号的图片需要转义才可以显示 狼人:
    近百余款最新HTML5应用案例给大伙儿共享了 狼人:
    shopex李钟伟:独立电子商务发展与网络购物 狼人:
    《天将客户关系管理系统》 狼人:
    Shopex V4.8.4 V4.8.5 后台拿Shell 0Days 狼人:
  • 原文地址:https://www.cnblogs.com/legu/p/5712317.html
Copyright © 2011-2022 走看看