上一篇文章大概讲述了js项目开发的整体流程,在这篇文章中我们着重讲解关于代理的部分。
先整体讲一下关于代理的过程:
- 首先我们先用express(当然也可以是其他的node服务框架)在本地启动一个server服务。
- 将静态资源的host映射到本地,比如测试环境静态资源网址是m.asset.com,那么可以使用修改host的工具switchhost修改m.asset.com的host为127.0.0.1。
- 在本地的server服务对请求进行过滤,将请求打到本地webpack打包服务上,获取对应的js资源,然后返回给浏览器。
接下来是实现这个代理服务的不完全代码,但是包括了最核心的部分。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
let express = require('express'),
proxy = require('http-proxy-middleware');
let app = express();
if (process.env.PROTOCOL_ENV === 'https') {
httpsCreate();
} else {
httpCreate();
}
// 将css和图片等资源修改host代理到测试环境访问
function beforeProxy(urlStr, port) {
let reg = new RegExp('27.27.27.27');// 这个ip地址是自定义的
port = port || 9002;
return function(req, res, next) {
let rHost = req.host,
rHost = rHost.replace('m', 'mz');
isTest = req.headers.host.indexOf('test') === 0,
url = urlStr;
if (isTest) {
// 如果urlStr是不包含ip地址的,那么经过一下这一步是url不会发生变化
url = url.replace(reg, '$1:' + port);
}
return proxy({
target: 'http://' + rHost,
router: {
'^/other_asset': url
},
toProxy: true
}).call(null, req, res, next);
};
}
// http的启动服务
function httpCreate() {
app.use('/', (req, res, next) => {
res.header('Access-Control-Allow-Origin', '*');
next();
});
// css静态资源域名和js一样,通过修改域名的方式
// 直接请求对应环境的资源,要么是为修改之后的域名绑定了host,要么为这个host做自动映射
app.use('/other_asset', beforeProxy('/other_asset'));
// 本地启动的pc js打包服务
app.use('/js/pc', proxy('http://localhost:9090/js/pc'));
// 本地启动的h5 js打包服务
app.use('/js/h5', proxy('http://localhost:3002/js/h5'));
app.listen(80, 'm.asset.com', (err) => {
// 这里启动服务的时候需要确保能够找到m.asset.com的host
// 不然启动会报错
if (err) {
console.log(err);
return;
}
});
}
// 代理https下的pc js请求
function proxyPC(req, res, next) {
proxy({
target: 'http://localhost:9090',
ssl: httpsServer,
secure: false,
pathRewrite: {
'^/js/pc': '/js/pc'
},
protocolRewrite: 9090
}).call(null, req, res, next);
}
// 代理https下的h5 js请求
function proxyH5(req, res, next) {
let _pt = path.join(process.cwd(), 'h5/pages');
req.url.replace(/\.js\?.*/, '/index.js');
fs.exist(_pt, exist => {
if (exist) {
return proxy({
target: 'https://localhost:3002',
ssl: httpsServer,
secure: false,
pathRewrite: {
'^/js/h5': '/js/h5'
},
protocolRewrite: 9090
}).call(req, res, next);
} else {
console.log('h5 js directory does not exist.');
}
});
}
// https的启动服务
let fs = require('fs'),
https = require('https'),
path = require('path'),
options = {
key: fs.readFileSync(path.join(__dirname, '../key.pem')),
cert: fs.readFileSync(path.join(__dirname, '../cert.pem'))
};
let httpsServer;
function httpsCreate() {
// 防止代理请求https地址时,https证书不被信任而被拦截
// 如果不设置这个环境变量,会出现CERT_UNTRUSTED问题
process.env.NODE_TLS_REJECT_UNAUTHORIZED = "0";
app.use('/', (req, res, next) => {
res.header('Access-Control-Allow-Origin', "*");
next();
});
app.use('/other_asset', beforeProxy('/other_asset'));
app.use('/js/pc', proxyPC);
app.use('/js/h5', proxyH5);
httpsServer = https.createServer(options, app);
httpServer.listen(443, 'm.asset.com', (err) => {
if (err) {
console.log(err);
return;
}
});
}