{"id":15289006,"url":"https://github.com/kouyjes/node-server","last_synced_at":"2025-04-13T08:11:51.577Z","repository":{"id":44860923,"uuid":"71212661","full_name":"kouyjes/node-server","owner":"kouyjes","description":"http-server node-http-server node-server windows linux mac proxy","archived":false,"fork":false,"pushed_at":"2022-12-07T18:29:30.000Z","size":177,"stargazers_count":3,"open_issues_count":3,"forks_count":0,"subscribers_count":0,"default_branch":"master","last_synced_at":"2025-04-13T08:11:39.564Z","etag":null,"topics":["cluster-server","controller","filter","http","http-proxy","http-proxy-","http-proxy-middleware","http-server","linux","mac","middleware","mvc","nginx","node-http-server","node-mvc","node-proxy-server","proxy-server","server","session","windows"],"latest_commit_sha":null,"homepage":"","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/kouyjes.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2016-10-18T05:38:30.000Z","updated_at":"2020-03-17T01:59:52.000Z","dependencies_parsed_at":"2023-01-24T20:16:13.809Z","dependency_job_id":null,"html_url":"https://github.com/kouyjes/node-server","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kouyjes%2Fnode-server","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kouyjes%2Fnode-server/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kouyjes%2Fnode-server/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kouyjes%2Fnode-server/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/kouyjes","download_url":"https://codeload.github.com/kouyjes/node-server/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248681497,"owners_count":21144700,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["cluster-server","controller","filter","http","http-proxy","http-proxy-","http-proxy-middleware","http-server","linux","mac","middleware","mvc","nginx","node-http-server","node-mvc","node-proxy-server","proxy-server","server","session","windows"],"created_at":"2024-09-30T15:55:34.080Z","updated_at":"2025-04-13T08:11:51.552Z","avatar_url":"https://github.com/kouyjes.png","language":"JavaScript","readme":"# node-server\nnode-server是一个用node实现的web服务器，支持基本的反向代理、node开发后端应用。\n\n### node\n### Get Starting\n### 配置文件\nnode-server的配置文件位于conf目录下，是一个正常的node模块，config.demo.js为config的配置说明。\n\n### 静态资源服务器配置\n```javascript\nexports.config = {\n    contexts:[\n        {\n            path:'/', //配置\n            docBase:[\n                '/workspace' //配置静态资源目录绝对地址\n                //{dir:'/workspace'} //以对象方式定义docBase\n                //{dir:'/workspace',path:'/work'} 定义每个工作目录的path\n            ],\n            port:8080\n            //port:[8080,8081]\n        }\n    ]\n};\n```\n\n### 代理服务器配置\n```javascript\nexports.config = {\n    contexts:[\n        {\n            ...\n            proxy:{\n                protocol:null,\n                pathRule:'^/api',\n                server:'192.168.1.100',\n                port:80,\n                headers:{}\n            }\n        }\n    ]\n};\n```\nproxy:配置代理，为一个对象或是数组，如配置为数组，则会根据顺序选择满足pathRule规则的代理。\u003cbr/\u003e\nprotocol:定义代理的协议，默认与请求协议一致 \u003cbr/\u003e\npathRule:配置代理的代理规则，为一个正则字符串,如：'^/api' \u003cbr/\u003e\nserver:配置代理服务器IP \u003cbr/\u003e\nport:配置代理服务器端口，默认与请求端口一致 \u003cbr/\u003e\nheaders:配置发送到代理服务器需要添加的header\u003cbr/\u003e\nurl:【optional】配置重写url\n\n\n### 会话配置\nnode-server会话默认是关闭的，当session配置有效时会启用会话，会话存储默认提供2中方式，文件会话存储于redis会话存储。\n\n#### 文件会话存储\n```javascript\nexports.config = {\n    contexts:[\n        {\n            ...\n            session:{\n                provider:{\n                    type:'file',\n                    dataFile:'/data/log/session.data'\n                },\n                timeout:30\n            }\n        }\n    ]\n};\n```\nprovider:会话提供者\u003cbr/\u003e\ntype:配置会话持久化类型\u003cbr/\u003e\ndataFile:配置会话存储的文件，实际情况会话文件后会附加相关的上下文信息\u003cbr/\u003e\ntimeout:配置会话有效期，单位为分\u003cbr/\u003e\n\n#### redis会话存储\n```javascript\nexports.config = {\n    contexts:[\n        {\n            ...\n            session:{\n                provider:{\n                    type:'redis',\n                    host:'127.0.0.1',\n                    port:7050,\n                    password:''\n                },\n                timeout:30\n            }\n        }\n    ]\n};\n```\nhost:配置redis主机地址\u003cbr/\u003e\nport:配置redis端口\u003cbr/\u003e\npassword:配置redis连接密码\u003cbr/\u003e\n\n#### 会话提供方式扩展\n如果两种会话方式不满足实际需求，可对会话提供方式进行扩展，会话实现需要继承抽象类Session，会话提供者需要实现抽象类SessionProvider，然后在session/impl.json\n中进行配置即可。\n\n\n### server的协议支持\nnode-server协议类型支持http|http2|https\n\n#### http\n```javascript\nexports.config = {\n    contexts:[\n        {\n            ...\n            protocol:'http'\n        }\n    ]\n};\n```\nprotocol:定义协议类型，默认是http协议\n\n#### https\n```javascript\nexports.config = {\n    contexts:[\n        {\n            ...\n            protocol:'https',\n            key:filePath.resolve('conf/private.pem'),\n            cert:filePath.resolve('conf/file.crt')\n        }\n    ]\n};\n```\nhttps协议需要配置私钥与证书路径\n\n#### http2\n```javascript\nexports.config = {\n    contexts:[\n        {\n            ...\n            protocol:'http2',\n            key:filePath.resolve('conf/private.pem'),\n            cert:filePath.resolve('conf/file.crt')\n        }\n    ]\n};\n```\n\n#### combo属性，当combo为true时允许请求多个静态资源\n```javascript\nexports.config = {\n    contexts:[\n        {\n            ...\n            combo:true\n        }\n    ]\n};\n//请求url格式 http://localhost??app/test.js,js/common.js\n//注意多个?(＞＝2)为识别符 如：http://localhost????app/test.js,js/common.js\n// http://localhost/app/comp??a.js,b.js,c.js\n```\n\n\n### 配置上下文属性\n```javascript\nexports.config = {\n    contexts:[\n        {\n            ...\n            attributes:{anonymous:false}\n        }\n    ]\n};\n```\nattributes:定义上下文属性，可以通过config对象获取\n\n\n####  node-server 完整配置说明\n```javascript\n/**\n *\n * @type {{logFilePath: string, multiProcess: boolean, contexts: *[]}}\n *\n * 服务器启动过程中会对context中配置进行解析，对每一个context的dir目录进行扫描，对controllers和filters字段设定的目录解析\n * 生成映射规则和过滤器,默认值为controllers和filters\n *\n * context中字段配置说明\n * dir 用户工作目录\n * controllers 用户控制器逻辑,可根据目录路径生成请求路径和控制规则关系\n * filters 用户过滤器，根据每个过滤器的priority字段决定调用次序\n * path  上下文路径，此路径会比context.path优先使用\n */\n \n var filePath = require('../file/file-path');\nconfig = {\n    debugMode:false,\n    multiProcess:false, //是否对多个contexts启动多进程\n    contexts:[\n        {\n            serverName:'x3 nodejs server', //服务器名称\n            multiCpuSupport:false,//根据CPU数量,启动多个进程,配置为true时，需要配置为redis session\n            zipResponse:true,//对输出进行压缩\n            protocol:null,//【optional default http】协议定义\n            sessionCookieName:null,//【optional】\n            sessionCookiePath:null,//【optional default /】\n            //protocol:'https', // 【default http】\n            //key:filePath.resolve('conf/private.pem'), //\n            //cert:filePath.resolve('conf/file.crt'), //\n            //serverOption:【optional default null】服务器创建时其他选项参数\n            //disabledAgentCache:true, //禁用客户端缓存\n            docBase:[  //服务器工作目录\n                {dir:'/'},//{dir:'目录名称',controllers:'controllers',filters:'filters',path:'/'}\n                '/workdpace',\n                {dir:'/',path:'/ctx'}\n            ],\n            //optional 不配置session时不会启用session\n            session:{\n                provider:{\n                    type:'file',//会话持久化机制\n                    dataFile:'/data/log/session.data' //会话文件\n                },\n                /*\n                provider:{\n                    type:'redis',\n                    host:'127.0.0.1'\n                    //port password\n                },\n                */\n                timeout:30,//会话过期时间，单位为分，默认30分钟\n            },\n            path:'/',//上下文路径\n            port:[8080], //服务器监听端口,可配置多个\n            attributes:{anonymous:false}, //配置自定义属性\n            combo:true, //合并请求资源\n            proxy:{\n                protocol:null,//【optional default http】 协议定义 \n                pathRule:null,//【required】配置需要代理url的匹配规则，为正则表达式字符串\n                server:'192.168.1.100', //配置服务端IP\n                port:80, //【optional】配置服务端端口，如不配置则与请求端口一致\n                headers:{}, //【optional】配置发送请求时需要添加的header\n                url:null //【optional】配置重写url\n            }\n        }\n    ]\n};\n```\n\n### node-server实现原理\n对于每个context会启动一个node子进程，每个进程是相对独立的。\u003cbr/\u003e\nnode-server包含很多filter与dispatcher，每个filter负责不同的职责以及对request的加工。\u003cbr/\u003e\n#### 内置filter\nrequest-response-wrapper 实现常用的接口调用\u003cbr/\u003e\nrequest-session-wrapper 负责session部分\u003cbr/\u003e\nrequest-cookie-wrapper 负责cookie部分\u003cbr/\u003e\nrequest-response-304 负责缓存部分\u003cbr/\u003e\ncros-filter 负责一些跨域请求的处理\u003cbr/\u003e\nproxy-* 负责代理\u003cbr/\u003e\n\n#### 内置dispatcher\nControllerDispatcher 负责用户node程序接口的调用\u003cbr/\u003e\nStaticResourceDispatcher 静态资源转发\u003cbr/\u003e\n\n#### 用户filter定义\nnode-server默认会解析用户工作目录下filters目录，并解析目录中js文件的filter\n\n```javascript\nfunction loginFilter(chain,request,response){\n    //todo\n    chain.next();\n}\nloginFilter.priority = 1; //[optional]\nexports.execute = loginFilter\n```\nfilter文件是一个node模块，包含execute方法则被视为有效的filter，execute方法调用时会传入3个参数。\u003cbr/\u003e\nchain:filter链，每个filter执行后需调用chain.next()将请求移交给下一个filter，如不需要移交，则不需要调用。\u003cbr/\u003e\nrequest:代表请求对象\u003cbr/\u003e\nresponse：代表响应对象\u003cbr/\u003e\npriority:filter的优先级，默认为0，系统内置的filter调用优先于用户定义的filter\u003cbr/\u003e\n\n\n\n###  Controller定义\n```javascript\nfunction getUsers(request,response){\n    var users = [];\n    var result = JSON.stringify(users);\n    response.outputContent(result,'application/json');\n}\nexports.users = getUsers;\n\n//request url http://localhost/users\n\n//you can also change default url mapping rule\nfunction getBooks(request response){\n    var pathParams = request.pathParams;\n    var userId = pathParams.userId;\n    var books = [];\n    var result = JSON.stringify(books);\n    response.outputContent(result,'application/json');\n}\ngetBooks.$mappingUrl = '/users/{userId}'\nexports.books = getBooks;\n//request url http://localhost/users/123\n```\nserver启动时会扫描用户工作目录下的controllers目录以及子目录js文件\n\n每个controller也是一个node模块，exports中的每个方法对应controller的一个接口\u003cbr/\u003e\nfunction的$mappingUrl属性定义接口的url，没有此属性时，server会根据目录的层次生成默认的接口url\u003cbr/\u003e\nfunction的$methods定义接口调用允许的http METHOD,为数组或字符串\u003cbr/\u003e\n\n\n\n### Node Api启动server\n```javascript\nvar server = require('nm-web-server');\nvar config = {\n    contexts:[\n        {\n            ...\n        }\n    ]\n};\nserver.startServer(config);\n```\n\n### API\nRequest\u003cbr/\u003e\ngetContextConfig() 获取上下文配置\u003cbr/\u003e\ngetAttribute(key) 返回属性\u003cbr/\u003e\nsetAttribute(key,value)设置属性\u003cbr/\u003e\ncreateCookie(name,value) 创建Cookie，返回Cookie实例\ngetCookie(name) 获取Cookie\u003cbr/\u003e\ngetSession() 获取session对象\u003cbr/\u003e\u003cbr/\u003e\n\nSession\u003cbr/\u003e\nsetAttributes(property)设置属性\u003cbr/\u003e\ngetAttribute(name,async)获取属性\u003cbr/\u003e\ninvalid()\u003cbr/\u003e\ngetId()\u003cbr/\u003e\u003cbr/\u003e\n\nResponse\u003cbr/\u003e\ncreateCookie(name,value) 创建Cookie，返回Cookie实例\u003cbr/\u003e\naddCookie(cookie) 添加Cookie\u003cbr/\u003e\nremoveCookie(name) 删除Cookie\u003cbr/\u003e\noutputContent(content,mime)输出内容\u003cbr/\u003e\nzipOutputContent(mime,content,encoding)压缩输出内容\u003cbr/\u003e\nsendError(errorCode,message) 输出错误响应\u003cbr/\u003e\noutputStaticResource(absPath)根据路径输出资源内容\u003cbr/\u003e\nzipOutputStaticResource(absPath,encoding)根据路径压缩输出资源内容\u003cbr/\u003e\n\n\n\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fkouyjes%2Fnode-server","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fkouyjes%2Fnode-server","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fkouyjes%2Fnode-server/lists"}