Nginx 支持这么一种资源加载方式,
1 | http://xx.xx.com??a.js,b.js,c.js |
同一个路径下,双问号后是同一类型逗号分隔的文件名称,效果是服务端合并这几个文件成一个文件进行传输;linux 下的nginx模块nginx_concat_module很容易实现,但是windows下的nginx却没有这个功能,所以开发调试这种资源链接异常不便。但是偶然发现fiddler编写一些脚本就可以这种资源合并。
Talk is cheap ,show me your code
头部添加如下三个 import1
2
3import System.Text;
import System.Text.Encoding;
import System.IO.File;
class Handlers 后面下添加如下配置1
2
3
4
5
6
7
8
9
10
11class Handlers{
//域名和本地文件夹的映射关联,即 r.xxx.cn 域名下的资源都映射到本地的 c:/resources 路径下
static var COMBO_CONFIG = {
'r.xxx.cn' : {
dir : "c:/resources"
}
};
...
...
...其他省略代码
class Handlers 添加以下几个方法: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
121static function OnCombo(oSession : Session) {
if (!(oSession.host in COMBO_CONFIG)) {
FiddlerObject.log(oSession.host + " is not config");
return;
}
var target = "??";
var url = oSession.url;
var s = url.IndexOf(target);
if (s < 0) {
//非combo url
target = "";
s = url.IndexOf(oSession.host) + oSession.host.Length;
}
var BASE_DIR = COMBO_CONFIG[oSession.host].dir;
var e = url.IndexOf("?", s + target.Length);
var filesText = "";
if (e < 0) {
filesText = url.Substring(s + target.Length);
} else {
filesText = url.Substring(s + target.Length, e - (s + target.Length));
}
var afterHostIndex = url.IndexOf(oSession.host) + oSession.host.Length;
var files = filesText.Split(",");
var path = url.Substring(afterHostIndex, s - afterHostIndex);
var parentDir = BASE_DIR + path;
var encoding = Encoding.Default;
var content = GetFileContent(parentDir, files);
oSession.utilCreateResponseAndBypassServer();
if (encoding == System.Text.Encoding.UTF8) {
oSession.utilSetResponseBody(content);
} else {
oSession.ResponseBody = encoding.GetBytes(content.ToString());
}
var contentType = "application/javascript; charset=" + encoding.BodyName;
if (filesText.Contains(".css")) {
contentType = "text/css; charset=" + encoding.BodyName; ;
}
oSession.oResponse.headers.Add("Content-Type", contentType);
oSession.oResponse.headers.Add("Date", System.DateTime.Now.ToString());
oSession.oResponse.headers.Add("Server", "fiddler");
oSession.oResponse.headers.Add("x-fiddler-combo", "HIT");
}
static function GetFileContent(parentDir : String, files : String[]) {
var content = new System.Text.StringBuilder();
var encoding = Encoding.Default;
for (var i = 0; i < files.Length; i++) {
var fileName = files[i];
if (!System.IO.File.Exists(parentDir + fileName)) {
FiddlerObject.log(fileName + " is not exist!");
continue;
}
encoding = GetEncoding(parentDir + fileName, Encoding.Default);
content.Append(System.IO.File.ReadAllText(parentDir + fileName, encoding)); //
}
return content;
}
static function GetEncoding(file : String, defEnc : System.Text.Encoding) {
var stream = System.IO.File.OpenRead(file);{
//判断流可读?
if (!stream.CanRead)
return null;
//字节数组存储BOM
var bom = new byte[4];
//实际读入的长度
var readc = 0;
readc = stream.Read(bom, 0, 4);
stream.Close();
if (readc >= 2) {
if (readc >= 4) {
//UTF32,Big-Endian
if (CheckBytes(bom, 4, [0x00, 0x00, 0xFE, 0xFF]))
return new UTF32Encoding(true, true);
//UTF32,Little-Endian
if (CheckBytes(bom, 4, [0xFF, 0xFE, 0x00, 0x00]))
return new UTF32Encoding(false, true);
}
//UTF8
if (readc >= 3 && CheckBytes(bom, 3, [0xEF, 0xBB, 0xBF]))
return new UTF8Encoding(true);
//UTF16,Big-Endian
if (CheckBytes(bom, 2, [0xFE, 0xFF]))
return new UnicodeEncoding(true, true);
//UTF16,Little-Endian
if (CheckBytes(bom, 2, [0xFF, 0xFE]))
return new UnicodeEncoding(false, true);
}
return defEnc;
}
}
//辅助函数,判断字节中的值
static function CheckBytes(bytes : byte[], count : int, values : int[]) {
for (var i = 0; i < count; i++)
if (bytes[i] != values[i])
return false;
return true;
}
使用方法
可以直接从 fiddlerScript 标签中贴入代码
- 或者先安装fiddler的编辑插件,之后贴入代码()
COMBO_CONFIG 中 r.xxx.cn 换为你需要替换的域名,dir 值改为你本地资源所在的文件夹,注意路径分隔符要使用正斜线,比如这种:c:/resource
在 fiddler 的 AutoResponder 建立 如下规则:(假设要替换的 r.xxx.cn/js/??a.js,b.js,c.js)
假如成功的话,在 response header 中会看到这个特殊的头信息
完整的脚本放在 github 中
注意事项
- 现在只支持常用的 js css 资源的合并
- 因为是通过bom识别文件格式,所以当文件为 UTF-8 编码时,注意选择 带有 bom ,否则会乱码
Fiddler 脚本功能
Fiddler 是 windows 下web开发神器,功能强大,同时又支持脚本编写,
扩展性极其好。最后因为精力有限,没有实现用 C# 实现 图形界面。