oipage 0.3.1-alpha.0 → 0.3.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG +61 -61
- package/README.md +122 -122
- package/bin/options.js +73 -73
- package/bin/run +208 -208
- package/browserjs/getStyle/index.d.ts +10 -10
- package/browserjs/getStyle/index.js +12 -12
- package/browserjs/index.d.ts +12 -12
- package/browserjs/index.js +8 -8
- package/browserjs/onReady/index.d.ts +7 -7
- package/browserjs/onReady/index.js +7 -7
- package/browserjs/setStyle/index.d.ts +9 -9
- package/browserjs/setStyle/index.js +4 -4
- package/corejs/animation/index.d.ts +11 -11
- package/corejs/animation/index.js +101 -101
- package/corejs/index.d.ts +9 -9
- package/corejs/index.js +6 -6
- package/corejs/throttle/index.d.ts +30 -30
- package/corejs/throttle/index.js +49 -49
- package/nodejs/core/file.js +162 -162
- package/nodejs/core/image.js +4 -4
- package/nodejs/core/log.js +89 -89
- package/nodejs/core/network.js +39 -39
- package/nodejs/core/options.js +48 -48
- package/nodejs/core/remote.js +60 -60
- package/nodejs/core/responseFileList.js +27 -27
- package/nodejs/core/server.js +198 -198
- package/nodejs/data/404.js +51 -51
- package/nodejs/data/mime.types.js +111 -111
- package/nodejs/form/common.js +2 -2
- package/nodejs/form/index.js +79 -79
- package/nodejs/form/select.js +9 -9
- package/nodejs/index.js +57 -57
- package/nodejs/loader/simpleScss.js +247 -247
- package/nodejs/loader/xhtml.js +520 -520
- package/nodejs/reader/plain.js +20 -20
- package/package.json +33 -33
- package/stylecss/index.css +3 -3
- package/stylecss/normalize.css +93 -93
- package/stylecss/rasterize.css +317 -317
- package/stylecss/skeleton.css +16 -16
- package/types/get-options.d.ts +5 -5
- package/types/index.d.ts +186 -186
package/nodejs/core/server.js
CHANGED
|
@@ -1,199 +1,199 @@
|
|
|
1
|
-
const http = require('http');
|
|
2
|
-
const fs = require('fs');
|
|
3
|
-
|
|
4
|
-
const mineTypes = require('../data/mime.types.js');
|
|
5
|
-
const { log, warn, error } = require('./log.js');
|
|
6
|
-
const responseFileList = require('./responseFileList.js');
|
|
7
|
-
const path = require('path');
|
|
8
|
-
const network = require('./network.js');
|
|
9
|
-
|
|
10
|
-
const jsonfile = JSON.parse(fs.readFileSync(path.join(__dirname, '../../package.json')));
|
|
11
|
-
|
|
12
|
-
module.exports = function (config = {}) {
|
|
13
|
-
|
|
14
|
-
let port = config.port || 20000; // 端口号
|
|
15
|
-
let handler = typeof config.handler == 'function' ? config.handler : function () { return false; };
|
|
16
|
-
let suffixs = Array.isArray(config.suffix) ? config.suffix : [".html", ".htm", ".js", ".json", ".css"];
|
|
17
|
-
|
|
18
|
-
let proxy = [];
|
|
19
|
-
if (config.proxy) {
|
|
20
|
-
for (let item of config.proxy) {
|
|
21
|
-
let target = /(https*):\/\/([^/:]+):*(\d+)*(.*)/.exec(item.target) || [];
|
|
22
|
-
proxy.push({
|
|
23
|
-
test: item.test,
|
|
24
|
-
target: {
|
|
25
|
-
protocol: target[1], // 使用的协议
|
|
26
|
-
hostname: target[2], // 请求发送至的服务器的域名或 IP 地址
|
|
27
|
-
port: target[3] || 80, // 端口号
|
|
28
|
-
path: target[4] || "", // 路径前缀
|
|
29
|
-
}
|
|
30
|
-
});
|
|
31
|
-
}
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
let basePath = path.join(process.cwd(), config.basePath || "./"); // 服务器根路径
|
|
35
|
-
|
|
36
|
-
let index = 0;
|
|
37
|
-
let Server = http.createServer(function (request, response) {
|
|
38
|
-
try {
|
|
39
|
-
let requestData = "";
|
|
40
|
-
|
|
41
|
-
request.on('data', (chunk) => {
|
|
42
|
-
requestData += chunk;
|
|
43
|
-
});
|
|
44
|
-
|
|
45
|
-
request.on('end', () => {
|
|
46
|
-
let url = decodeURIComponent(request.url);
|
|
47
|
-
|
|
48
|
-
url = url.split("?")[0];
|
|
49
|
-
|
|
50
|
-
// 请求的文件路径
|
|
51
|
-
let filePath = path.join(basePath, url == "/" ? "index.html" : url.replace(/^\//, ""));
|
|
52
|
-
|
|
53
|
-
log("[" + index++ + "]" + url);
|
|
54
|
-
|
|
55
|
-
let getFileInfo = function (filePath) {
|
|
56
|
-
let dotName = /\./.test(filePath) ? filePath.match(/\.([^.]+)$/)[1] : "";
|
|
57
|
-
let type = mineTypes[dotName];
|
|
58
|
-
if (fs.existsSync(filePath) && !fs.lstatSync(filePath).isDirectory()) {
|
|
59
|
-
return {
|
|
60
|
-
type,
|
|
61
|
-
path: filePath
|
|
62
|
-
};
|
|
63
|
-
} else {
|
|
64
|
-
for (let suffix of suffixs) {
|
|
65
|
-
if (fs.existsSync(filePath + suffix) && !fs.lstatSync(filePath + suffix).isDirectory()) {
|
|
66
|
-
type = mineTypes[suffix.replace(/^\./, "")];
|
|
67
|
-
return {
|
|
68
|
-
type,
|
|
69
|
-
path: filePath + suffix
|
|
70
|
-
};
|
|
71
|
-
}
|
|
72
|
-
}
|
|
73
|
-
}
|
|
74
|
-
};
|
|
75
|
-
|
|
76
|
-
// 自定义拦截
|
|
77
|
-
if (handler.call({
|
|
78
|
-
data: requestData,
|
|
79
|
-
base: basePath,
|
|
80
|
-
getFileInfo,
|
|
81
|
-
filePath
|
|
82
|
-
}, request, response)) return;
|
|
83
|
-
|
|
84
|
-
// proxy拦截
|
|
85
|
-
for (let item of proxy) {
|
|
86
|
-
if (item.test.test(url)) {
|
|
87
|
-
let _path = item.target.path + (url.replace(item.test, ""));
|
|
88
|
-
|
|
89
|
-
warn(" ↳ [" + request.method + "] " + item.target.protocol + "://" + item.target.hostname + ":" + item.target.port + _path);
|
|
90
|
-
|
|
91
|
-
// https://www.nodeapp.cn/http.html#http_http_request_options_callback
|
|
92
|
-
const req = http.request({
|
|
93
|
-
hostname: item.target.hostname,
|
|
94
|
-
port: item.target.port,
|
|
95
|
-
path: _path,
|
|
96
|
-
method: request.method,
|
|
97
|
-
headers: request.headers
|
|
98
|
-
}, (res) => {
|
|
99
|
-
res.setEncoding('utf8');
|
|
100
|
-
|
|
101
|
-
let responseData = "";
|
|
102
|
-
res.on('data', (chunk) => {
|
|
103
|
-
responseData += chunk;
|
|
104
|
-
});
|
|
105
|
-
res.on('end', () => {
|
|
106
|
-
let responseHeaders = res.headers;
|
|
107
|
-
responseHeaders['proxy-server'] = "Powered by OIPage@" + jsonfile.version;
|
|
108
|
-
responseHeaders['Access-Control-Allow-Origin'] = '*';
|
|
109
|
-
response.writeHead(res.statusCode, responseHeaders);
|
|
110
|
-
response.write(responseData);
|
|
111
|
-
response.end();
|
|
112
|
-
});
|
|
113
|
-
});
|
|
114
|
-
|
|
115
|
-
req.on('error', (e) => {
|
|
116
|
-
error(` 转发的时候遇到问题: ${e.message}`);
|
|
117
|
-
response.writeHead('500', {
|
|
118
|
-
'Content-type': "text/plain;charset=utf-8",
|
|
119
|
-
'Access-Control-Allow-Origin': '*',
|
|
120
|
-
"proxy-server": "Powered by OIPage@" + jsonfile.version
|
|
121
|
-
});
|
|
122
|
-
response.write(e + "");
|
|
123
|
-
response.end();
|
|
124
|
-
});
|
|
125
|
-
|
|
126
|
-
req.write(requestData);
|
|
127
|
-
req.end();
|
|
128
|
-
|
|
129
|
-
return;
|
|
130
|
-
}
|
|
131
|
-
}
|
|
132
|
-
|
|
133
|
-
let is404 = true, needEnd = true;
|
|
134
|
-
let doResponse = function (type, filePath) {
|
|
135
|
-
|
|
136
|
-
let fileInfo = fs.statSync(filePath);
|
|
137
|
-
|
|
138
|
-
response.writeHead(200, {
|
|
139
|
-
'Content-type': (type || "text/plain") + ";charset=utf-8",
|
|
140
|
-
'Access-Control-Allow-Origin': '*',
|
|
141
|
-
'Content-Length': fileInfo.size,
|
|
142
|
-
'Server': "Powered by OIPage@" + jsonfile.version
|
|
143
|
-
});
|
|
144
|
-
if (fileInfo.size < 10 * 1024 * 1024) {
|
|
145
|
-
response.write(fs.readFileSync(filePath));
|
|
146
|
-
} else {
|
|
147
|
-
fs.createReadStream(filePath).pipe(response);
|
|
148
|
-
needEnd = false;
|
|
149
|
-
}
|
|
150
|
-
is404 = false;
|
|
151
|
-
};
|
|
152
|
-
|
|
153
|
-
let fileInfo = getFileInfo(filePath);
|
|
154
|
-
if (fileInfo) { // 如果文件存在
|
|
155
|
-
doResponse(fileInfo.type, fileInfo.path);
|
|
156
|
-
}
|
|
157
|
-
|
|
158
|
-
if (is404) {
|
|
159
|
-
response.writeHead(404, {
|
|
160
|
-
'Content-type': "text/html;charset=utf-8",
|
|
161
|
-
'Access-Control-Allow-Origin': '*',
|
|
162
|
-
'Server': "Powered by OIPage@" + jsonfile.version
|
|
163
|
-
});
|
|
164
|
-
response.write(responseFileList(filePath));
|
|
165
|
-
}
|
|
166
|
-
|
|
167
|
-
if (needEnd) response.end();
|
|
168
|
-
});
|
|
169
|
-
} catch (e) {
|
|
170
|
-
error(e);
|
|
171
|
-
|
|
172
|
-
response.writeHead(500, {
|
|
173
|
-
'Content-type': "text/plain;charset=utf-8",
|
|
174
|
-
'Access-Control-Allow-Origin': '*',
|
|
175
|
-
'Server': "Powered by OIPage@" + jsonfile.version
|
|
176
|
-
});
|
|
177
|
-
response.write(e + "");
|
|
178
|
-
|
|
179
|
-
response.end();
|
|
180
|
-
}
|
|
181
|
-
|
|
182
|
-
});
|
|
183
|
-
|
|
184
|
-
Server.listen(port);
|
|
185
|
-
|
|
186
|
-
// 打印启动成功信息
|
|
187
|
-
|
|
188
|
-
log('\n<i> [OIPage-server] Project is running at:');
|
|
189
|
-
log('<i> [OIPage-server] Loopback: http://localhost:' + port + '/');
|
|
190
|
-
|
|
191
|
-
let networkInfo = network();
|
|
192
|
-
|
|
193
|
-
// 打印IPv4地址
|
|
194
|
-
for (let ipv4 of networkInfo.IPv4) {
|
|
195
|
-
log('<i> [OIPage-server] On Your Network (IPv4): http://' + ipv4.address + ':' + port + '/');
|
|
196
|
-
}
|
|
197
|
-
|
|
198
|
-
log('\nOIPage Server compiled successfully\n');
|
|
1
|
+
const http = require('http');
|
|
2
|
+
const fs = require('fs');
|
|
3
|
+
|
|
4
|
+
const mineTypes = require('../data/mime.types.js');
|
|
5
|
+
const { log, warn, error } = require('./log.js');
|
|
6
|
+
const responseFileList = require('./responseFileList.js');
|
|
7
|
+
const path = require('path');
|
|
8
|
+
const network = require('./network.js');
|
|
9
|
+
|
|
10
|
+
const jsonfile = JSON.parse(fs.readFileSync(path.join(__dirname, '../../package.json')));
|
|
11
|
+
|
|
12
|
+
module.exports = function (config = {}) {
|
|
13
|
+
|
|
14
|
+
let port = config.port || 20000; // 端口号
|
|
15
|
+
let handler = typeof config.handler == 'function' ? config.handler : function () { return false; };
|
|
16
|
+
let suffixs = Array.isArray(config.suffix) ? config.suffix : [".html", ".htm", ".js", ".json", ".css"];
|
|
17
|
+
|
|
18
|
+
let proxy = [];
|
|
19
|
+
if (config.proxy) {
|
|
20
|
+
for (let item of config.proxy) {
|
|
21
|
+
let target = /(https*):\/\/([^/:]+):*(\d+)*(.*)/.exec(item.target) || [];
|
|
22
|
+
proxy.push({
|
|
23
|
+
test: item.test,
|
|
24
|
+
target: {
|
|
25
|
+
protocol: target[1], // 使用的协议
|
|
26
|
+
hostname: target[2], // 请求发送至的服务器的域名或 IP 地址
|
|
27
|
+
port: target[3] || 80, // 端口号
|
|
28
|
+
path: target[4] || "", // 路径前缀
|
|
29
|
+
}
|
|
30
|
+
});
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
let basePath = path.join(process.cwd(), config.basePath || "./"); // 服务器根路径
|
|
35
|
+
|
|
36
|
+
let index = 0;
|
|
37
|
+
let Server = http.createServer(function (request, response) {
|
|
38
|
+
try {
|
|
39
|
+
let requestData = "";
|
|
40
|
+
|
|
41
|
+
request.on('data', (chunk) => {
|
|
42
|
+
requestData += chunk;
|
|
43
|
+
});
|
|
44
|
+
|
|
45
|
+
request.on('end', () => {
|
|
46
|
+
let url = decodeURIComponent(request.url);
|
|
47
|
+
|
|
48
|
+
url = url.split("?")[0];
|
|
49
|
+
|
|
50
|
+
// 请求的文件路径
|
|
51
|
+
let filePath = path.join(basePath, url == "/" ? "index.html" : url.replace(/^\//, ""));
|
|
52
|
+
|
|
53
|
+
log("[" + index++ + "]" + url);
|
|
54
|
+
|
|
55
|
+
let getFileInfo = function (filePath) {
|
|
56
|
+
let dotName = /\./.test(filePath) ? filePath.match(/\.([^.]+)$/)[1] : "";
|
|
57
|
+
let type = mineTypes[dotName];
|
|
58
|
+
if (fs.existsSync(filePath) && !fs.lstatSync(filePath).isDirectory()) {
|
|
59
|
+
return {
|
|
60
|
+
type,
|
|
61
|
+
path: filePath
|
|
62
|
+
};
|
|
63
|
+
} else {
|
|
64
|
+
for (let suffix of suffixs) {
|
|
65
|
+
if (fs.existsSync(filePath + suffix) && !fs.lstatSync(filePath + suffix).isDirectory()) {
|
|
66
|
+
type = mineTypes[suffix.replace(/^\./, "")];
|
|
67
|
+
return {
|
|
68
|
+
type,
|
|
69
|
+
path: filePath + suffix
|
|
70
|
+
};
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
};
|
|
75
|
+
|
|
76
|
+
// 自定义拦截
|
|
77
|
+
if (handler.call({
|
|
78
|
+
data: requestData,
|
|
79
|
+
base: basePath,
|
|
80
|
+
getFileInfo,
|
|
81
|
+
filePath
|
|
82
|
+
}, request, response)) return;
|
|
83
|
+
|
|
84
|
+
// proxy拦截
|
|
85
|
+
for (let item of proxy) {
|
|
86
|
+
if (item.test.test(url)) {
|
|
87
|
+
let _path = item.target.path + (url.replace(item.test, ""));
|
|
88
|
+
|
|
89
|
+
warn(" ↳ [" + request.method + "] " + item.target.protocol + "://" + item.target.hostname + ":" + item.target.port + _path);
|
|
90
|
+
|
|
91
|
+
// https://www.nodeapp.cn/http.html#http_http_request_options_callback
|
|
92
|
+
const req = http.request({
|
|
93
|
+
hostname: item.target.hostname,
|
|
94
|
+
port: item.target.port,
|
|
95
|
+
path: _path,
|
|
96
|
+
method: request.method,
|
|
97
|
+
headers: request.headers
|
|
98
|
+
}, (res) => {
|
|
99
|
+
res.setEncoding('utf8');
|
|
100
|
+
|
|
101
|
+
let responseData = "";
|
|
102
|
+
res.on('data', (chunk) => {
|
|
103
|
+
responseData += chunk;
|
|
104
|
+
});
|
|
105
|
+
res.on('end', () => {
|
|
106
|
+
let responseHeaders = res.headers;
|
|
107
|
+
responseHeaders['proxy-server'] = "Powered by OIPage@" + jsonfile.version;
|
|
108
|
+
responseHeaders['Access-Control-Allow-Origin'] = '*';
|
|
109
|
+
response.writeHead(res.statusCode, responseHeaders);
|
|
110
|
+
response.write(responseData);
|
|
111
|
+
response.end();
|
|
112
|
+
});
|
|
113
|
+
});
|
|
114
|
+
|
|
115
|
+
req.on('error', (e) => {
|
|
116
|
+
error(` 转发的时候遇到问题: ${e.message}`);
|
|
117
|
+
response.writeHead('500', {
|
|
118
|
+
'Content-type': "text/plain;charset=utf-8",
|
|
119
|
+
'Access-Control-Allow-Origin': '*',
|
|
120
|
+
"proxy-server": "Powered by OIPage@" + jsonfile.version
|
|
121
|
+
});
|
|
122
|
+
response.write(e + "");
|
|
123
|
+
response.end();
|
|
124
|
+
});
|
|
125
|
+
|
|
126
|
+
req.write(requestData);
|
|
127
|
+
req.end();
|
|
128
|
+
|
|
129
|
+
return;
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
let is404 = true, needEnd = true;
|
|
134
|
+
let doResponse = function (type, filePath) {
|
|
135
|
+
|
|
136
|
+
let fileInfo = fs.statSync(filePath);
|
|
137
|
+
|
|
138
|
+
response.writeHead(200, {
|
|
139
|
+
'Content-type': (type || "text/plain") + ";charset=utf-8",
|
|
140
|
+
'Access-Control-Allow-Origin': '*',
|
|
141
|
+
'Content-Length': fileInfo.size,
|
|
142
|
+
'Server': "Powered by OIPage@" + jsonfile.version
|
|
143
|
+
});
|
|
144
|
+
if (fileInfo.size < 10 * 1024 * 1024) {
|
|
145
|
+
response.write(fs.readFileSync(filePath));
|
|
146
|
+
} else {
|
|
147
|
+
fs.createReadStream(filePath).pipe(response);
|
|
148
|
+
needEnd = false;
|
|
149
|
+
}
|
|
150
|
+
is404 = false;
|
|
151
|
+
};
|
|
152
|
+
|
|
153
|
+
let fileInfo = getFileInfo(filePath);
|
|
154
|
+
if (fileInfo) { // 如果文件存在
|
|
155
|
+
doResponse(fileInfo.type, fileInfo.path);
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
if (is404) {
|
|
159
|
+
response.writeHead(404, {
|
|
160
|
+
'Content-type': "text/html;charset=utf-8",
|
|
161
|
+
'Access-Control-Allow-Origin': '*',
|
|
162
|
+
'Server': "Powered by OIPage@" + jsonfile.version
|
|
163
|
+
});
|
|
164
|
+
response.write(responseFileList(filePath));
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
if (needEnd) response.end();
|
|
168
|
+
});
|
|
169
|
+
} catch (e) {
|
|
170
|
+
error(e);
|
|
171
|
+
|
|
172
|
+
response.writeHead(500, {
|
|
173
|
+
'Content-type': "text/plain;charset=utf-8",
|
|
174
|
+
'Access-Control-Allow-Origin': '*',
|
|
175
|
+
'Server': "Powered by OIPage@" + jsonfile.version
|
|
176
|
+
});
|
|
177
|
+
response.write(e + "");
|
|
178
|
+
|
|
179
|
+
response.end();
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
});
|
|
183
|
+
|
|
184
|
+
Server.listen(port);
|
|
185
|
+
|
|
186
|
+
// 打印启动成功信息
|
|
187
|
+
|
|
188
|
+
log('\n<i> [OIPage-server] Project is running at:');
|
|
189
|
+
log('<i> [OIPage-server] Loopback: http://localhost:' + port + '/');
|
|
190
|
+
|
|
191
|
+
let networkInfo = network();
|
|
192
|
+
|
|
193
|
+
// 打印IPv4地址
|
|
194
|
+
for (let ipv4 of networkInfo.IPv4) {
|
|
195
|
+
log('<i> [OIPage-server] On Your Network (IPv4): http://' + ipv4.address + ':' + port + '/');
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
log('\nOIPage Server compiled successfully\n');
|
|
199
199
|
};
|
package/nodejs/data/404.js
CHANGED
|
@@ -1,52 +1,52 @@
|
|
|
1
|
-
const img_folder = require("./images/folder");
|
|
2
|
-
const img_file = require("./images/file");
|
|
3
|
-
|
|
4
|
-
module.exports = function (template) {
|
|
5
|
-
return `<!DOCTYPE html>
|
|
6
|
-
<html lang="zh-cn">
|
|
7
|
-
|
|
8
|
-
<head>
|
|
9
|
-
<meta charset="UTF-8">
|
|
10
|
-
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
11
|
-
<meta http-equiv="X-UA-Compatible" content="ie=edge">
|
|
12
|
-
<title>404 Not Found</title>
|
|
13
|
-
<style>
|
|
14
|
-
body{
|
|
15
|
-
margin: 0px;
|
|
16
|
-
background-color:#fcfcfc;
|
|
17
|
-
display: flex;
|
|
18
|
-
flex-wrap:wrap;
|
|
19
|
-
padding:100px;
|
|
20
|
-
}
|
|
21
|
-
body>a{
|
|
22
|
-
text-decoration: none;
|
|
23
|
-
padding:10px;
|
|
24
|
-
color:#000000;
|
|
25
|
-
text-align:center;
|
|
26
|
-
width:100px;
|
|
27
|
-
background-repeat: no-repeat;
|
|
28
|
-
background-position: center 0px;
|
|
29
|
-
padding-top: 65px;
|
|
30
|
-
margin-top: 50px;
|
|
31
|
-
font-size:12px;
|
|
32
|
-
}
|
|
33
|
-
body>a:hover{
|
|
34
|
-
outline:1px solid #55b9e6;
|
|
35
|
-
}
|
|
36
|
-
body>a.folder{
|
|
37
|
-
background-image:url('${img_folder}');
|
|
38
|
-
}
|
|
39
|
-
body>a.file{
|
|
40
|
-
background-image:url('${img_file}');
|
|
41
|
-
}
|
|
42
|
-
</style>
|
|
43
|
-
</head>
|
|
44
|
-
|
|
45
|
-
<body>
|
|
46
|
-
|
|
47
|
-
${template}
|
|
48
|
-
|
|
49
|
-
</body>
|
|
50
|
-
|
|
51
|
-
</html>`;
|
|
1
|
+
const img_folder = require("./images/folder");
|
|
2
|
+
const img_file = require("./images/file");
|
|
3
|
+
|
|
4
|
+
module.exports = function (template) {
|
|
5
|
+
return `<!DOCTYPE html>
|
|
6
|
+
<html lang="zh-cn">
|
|
7
|
+
|
|
8
|
+
<head>
|
|
9
|
+
<meta charset="UTF-8">
|
|
10
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
11
|
+
<meta http-equiv="X-UA-Compatible" content="ie=edge">
|
|
12
|
+
<title>404 Not Found</title>
|
|
13
|
+
<style>
|
|
14
|
+
body{
|
|
15
|
+
margin: 0px;
|
|
16
|
+
background-color:#fcfcfc;
|
|
17
|
+
display: flex;
|
|
18
|
+
flex-wrap:wrap;
|
|
19
|
+
padding:100px;
|
|
20
|
+
}
|
|
21
|
+
body>a{
|
|
22
|
+
text-decoration: none;
|
|
23
|
+
padding:10px;
|
|
24
|
+
color:#000000;
|
|
25
|
+
text-align:center;
|
|
26
|
+
width:100px;
|
|
27
|
+
background-repeat: no-repeat;
|
|
28
|
+
background-position: center 0px;
|
|
29
|
+
padding-top: 65px;
|
|
30
|
+
margin-top: 50px;
|
|
31
|
+
font-size:12px;
|
|
32
|
+
}
|
|
33
|
+
body>a:hover{
|
|
34
|
+
outline:1px solid #55b9e6;
|
|
35
|
+
}
|
|
36
|
+
body>a.folder{
|
|
37
|
+
background-image:url('${img_folder}');
|
|
38
|
+
}
|
|
39
|
+
body>a.file{
|
|
40
|
+
background-image:url('${img_file}');
|
|
41
|
+
}
|
|
42
|
+
</style>
|
|
43
|
+
</head>
|
|
44
|
+
|
|
45
|
+
<body>
|
|
46
|
+
|
|
47
|
+
${template}
|
|
48
|
+
|
|
49
|
+
</body>
|
|
50
|
+
|
|
51
|
+
</html>`;
|
|
52
52
|
};
|