Skip to content

Commit 9c33fd3

Browse files
committed
feat: 脚本链接叠加参数调整
1 parent d2ca315 commit 9c33fd3

File tree

4 files changed

+115
-112
lines changed

4 files changed

+115
-112
lines changed

package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "sub-store-front-end",
3-
"version": "2.15.9",
3+
"version": "2.15.10",
44
"private": true,
55
"scripts": {
66
"dev": "vite --host",

src/locales/en.ts

+10-4
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,7 @@ export default {
9393
url: {
9494
label: "URL",
9595
placeholder:
96-
"URL (please separate multiple urls with a new line). Supported parameters: noCache - do not use cache; insecure - do not verify the server certificate. For example: http://a.com#noCache",
96+
"URL (please separate multiple urls with a new line). Supported parameters: noCache - do not use cache; insecure - do not verify the server certificate. For example: http://a.com#noCache&insecure",
9797
isEmpty: "URL cannot be empty",
9898
isIllegal: "Invalid URL",
9999
},
@@ -525,11 +525,15 @@ export default {
525525
options: ["Link", "Script"],
526526
des: ["Type", "Content"],
527527
placeholder:
528-
"Input Script Link or Internal File like /api/file/name. In addition to the parameters of the script itself, there is support for additional parameters: noCache - do not use cache. For example: http://a.com#a=1&b=2#noCache",
528+
"Input Script Link or Internal File like /api/file/name. In addition to the parameters of the script itself, there is support for additional parameters: noCache - do not use cache, insecure - do not verify the server certificate. For example: http://a.com#a=1&b=2#noCache&insecure",
529529
openEditorBtn: "Open Code Editor",
530530
tipsTitle: "Script Filter Tips",
531531
tipsDes: "Use a JavaScript script to filter nodes",
532+
helpTitle: 'Tips',
533+
noCache: 'noCache',
534+
insecure: 'insecure',
532535
noCacheTips: 'When the cache is turned off, the script is refetched for each request.',
536+
insecureTips: 'When the insecure is turned on, the server certificate will not be verified.',
533537
paramsEditTips: 'Visual parameter editor, duplicate key names will adopt the principle of prioritizing the latter value.',
534538
paramsAdd: 'Add',
535539
paramsDelete: 'Delete',
@@ -542,14 +546,16 @@ export default {
542546
options: ["Link", "Script"],
543547
des: ["Type", "Content"],
544548
placeholder:
545-
"Input Script Link or Internal File like /api/file/name. In addition to the parameters of the script itself, there is support for additional parameters: noCache - do not use cache. For example: http://a.com#a=1&b=2#noCache",
549+
"Input Script Link or Internal File like /api/file/name. In addition to the parameters of the script itself, there is support for additional parameters: noCache - do not use cache, insecure - do not verify the server certificate. For example: http://a.com#a=1&b=2#noCache&insecure",
546550
openEditorBtn: "Open Code Editor",
547551
tipsTitle: "Script Operator Tips",
548552
tipsDes: "Use a JavaScript script to modify node information",
549553
paramsEdit: 'Edit Parameters',
550554
noCache: 'noCache',
551-
helpTitle: 'noCache Tips',
555+
insecure: 'insecure',
556+
helpTitle: 'Tips',
552557
noCacheTips: 'When the cache is turned off, the script is refetched for each request.',
558+
insecureTips: 'When the insecure is turned on, the server certificate will not be verified.',
553559
paramsEditTips: 'Visual parameter editor, duplicate key names will adopt the principle of prioritizing the latter value.',
554560
paramsAdd: 'Add',
555561
paramsDelete: 'Delete',

src/locales/zh.ts

+5-3
Original file line numberDiff line numberDiff line change
@@ -119,7 +119,7 @@ export default {
119119
},
120120
url: {
121121
label: '链接',
122-
placeholder: '链接(多个链接请换行) 支持参数: noCache 不使用缓存; insecure 不验证服务器证书. 例: http://a.com#noCache',
122+
placeholder: '链接(多个链接请换行) 支持参数: noCache 不使用缓存; insecure 不验证服务器证书. 例: http://a.com#noCache&insecure',
123123
isEmpty: '链接不能为空',
124124
isIllegal: '链接格式非法',
125125
},
@@ -414,12 +414,13 @@ export default {
414414
label: '脚本操作',
415415
options: ['链接', '脚本'],
416416
des: ['类型', '内容'],
417-
placeholder: '填入完整远程脚本链接 或 类似 /api/file/name 的内部文件调用路径. 除了脚本本身的参数外, 支持叠加参数: noCache 不使用缓存. 例: http://a.com#a=1&b=2#noCache',
417+
placeholder: '填入完整远程脚本链接 或 类似 /api/file/name 的内部文件调用路径. 除了脚本本身的参数外, 支持叠加参数: noCache 不使用缓存, insecure 不验证服务器证书. 例: http://a.com#a=1&b=2#noCache&insecure',
418418
openEditorBtn: '打开脚本编辑器',
419419
tipsTitle: '脚本操作操作提示',
420420
tipsDes: '使用一段 JavaScript 脚本来修改节点信息',
421421
paramsEdit: '参数编辑',
422422
noCache: '关闭缓存',
423+
insecure: '不验证服务器证书',
423424
helpTitle: '温馨提示',
424425
noCacheTips: '关闭缓存后, 每次请求都会重新获取脚本内容',
425426
paramsEditTips: '可视化参数编辑器,重复键名将采用后值优先原则',
@@ -540,12 +541,13 @@ export default {
540541
label: '脚本过滤',
541542
options: ['链接', '脚本'],
542543
des: ['类型', '内容'],
543-
placeholder: '填入完整远程脚本链接 或 类似 /api/file/name 的内部文件调用路径. 除了脚本本身的参数外, 支持叠加参数: noCache 不使用缓存. 例: http://a.com#a=1&b=2#noCache',
544+
placeholder: '填入完整远程脚本链接 或 类似 /api/file/name 的内部文件调用路径. 除了脚本本身的参数外, 支持叠加参数: noCache 不使用缓存, insecure 不验证服务器证书. 例: http://a.com#a=1&b=2#noCache&insecure',
544545
openEditorBtn: '打开脚本编辑器',
545546
tipsTitle: '脚本过滤器操作提示',
546547
tipsDes: '使用一段 JavaScript 脚本来过滤节点',
547548
paramsEdit: '参数编辑',
548549
noCache: '关闭缓存',
550+
insecure: '不验证服务器证书',
549551
helpTitle: '温馨提示',
550552
noCacheTips: '关闭缓存后, 每次请求都会重新获取脚本内容',
551553
paramsEditTips: '可视化参数编辑器,重复键名将采用后值优先原则',

src/views/editor/components/Script.vue

+99-104
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,17 @@
6666
@click.stop="showNoCacheTips"
6767
/>
6868
</div>
69+
<div v-if="value.mode === 'link'" class="title-label">
70+
<nut-switch v-model="params.insecure" />
71+
<span>
72+
{{ $t(`editorPage.subConfig.nodeActions['${type}'].insecure`) }}
73+
</span>
74+
<font-awesome-icon
75+
class="icon"
76+
icon="fa-solid fa-circle-question"
77+
@click.stop="showInsecureTips"
78+
/>
79+
</div>
6980
<!-- 添加参数按钮 -->
7081
<div v-if="showKeyValue" class="button">
7182
<div @click="addParameter">
@@ -113,140 +124,91 @@ const params = reactive({
113124
url: "",
114125
arguments: {},
115126
noCache: false,
127+
insecure: false,
116128
});
117129
118130
const paramsArguments = ref([]);
119131
120132
const parseUrlParams = (urlStr) => {
121-
let $arguments = {};
133+
let $arguments = {} as any;
134+
let otherArguments = {} as any;
122135
let noCache = false;
136+
let insecure = false;
123137
let url = urlStr?.trim() || "";
124138
125139
// 处理没有参数的情况
126140
if (!url) {
127-
return { url: "", arguments: {}, noCache: false };
141+
return { url: "", arguments: {}, noCache: false, insecure: false };
128142
}
129-
130-
// 处理URL末尾的所有 #noCache 标记
131-
while (url.endsWith("#noCache")) {
132-
url = url.slice(0, -8);
133-
noCache = true;
134-
}
135-
136-
// 安全的URL解码函数
137-
const safeDecodeURIComponent = (encodedURIComponent) => {
138-
if (!encodedURIComponent) return "";
139-
140-
try {
141-
return decodeURIComponent(encodedURIComponent);
142-
} catch (e) {
143-
// 尝试处理嵌套的URL编码
144-
let result = encodedURIComponent;
145-
let previousResult = "";
146-
let attempts = 0;
147-
const maxAttempts = 5;
148-
149-
while (result !== previousResult && attempts < maxAttempts) {
143+
// extract link arguments
144+
const rawArgs = url.split('#');
145+
try {
146+
if (rawArgs.length > 1) {
150147
try {
151-
previousResult = result;
152-
result = decodeURIComponent(previousResult);
153-
attempts++;
154-
} catch (decodeError) {
155-
return previousResult;
148+
// 支持 `#${encodeURIComponent(JSON.stringify({arg1: "1"}))}`
149+
$arguments = JSON.parse(decodeURIComponent(rawArgs[1]));
150+
} catch (e) {
151+
for (const pair of rawArgs[1].split('&')) {
152+
const key = pair.split('=')[0];
153+
const value = pair.split('=')[1];
154+
// 部分兼容之前的逻辑 const value = pair.split('=')[1] || true;
155+
$arguments[key] =
156+
value == null || value === ''
157+
? true
158+
: decodeURIComponent(value);
159+
}
156160
}
157-
}
158-
return result;
159161
}
160-
};
161-
162-
// 查找第一个 # 符号
163-
const hashIndex = url.indexOf("#");
164-
if (hashIndex === -1) {
165-
return { url, arguments: {}, noCache };
166-
}
167-
168-
// 提取基础URL和参数部分
169-
const baseUrl = url.substring(0, hashIndex);
170-
let paramsText = url.substring(hashIndex + 1);
171-
172-
// 处理参数部分的所有 #noCache 标记(支持在参数中间出现 #noCache)
173-
const parts = paramsText.split("#");
174-
const cleanParts = [];
175-
176-
for (const part of parts) {
177-
if (part === "noCache") {
178-
noCache = true;
179-
} else {
180-
cleanParts.push(part);
181-
}
182-
}
183-
184-
// 重新组合参数部分,排除noCache标记
185-
paramsText = cleanParts.join("#");
186-
187-
// 如果参数部分为空,则返回基本URL和noCache状态
188-
if (!paramsText) {
189-
return { url: baseUrl, arguments: {}, noCache };
162+
} catch (e) {
163+
console.error("Failed to parse URL parameters:", e);
164+
$arguments = {};
190165
}
191-
192-
// 尝试解析参数
193166
try {
194-
// 先尝试作为JSON解析
195-
try {
196-
const decodedParams = safeDecodeURIComponent(paramsText);
197-
if (decodedParams.startsWith("{") && decodedParams.endsWith("}")) {
198-
$arguments = JSON.parse(decodedParams);
199-
} else {
200-
throw new Error("Not a JSON object");
201-
}
202-
} catch (jsonError) {
203-
// JSON解析失败,使用&分割参数
204-
const pairs = paramsText.split("&");
205-
206-
for (const pair of pairs) {
207-
if (!pair) continue;
208-
209-
const equalIndex = pair.indexOf("=");
210-
if (equalIndex === -1) {
211-
// 没有等号,将整个值作为键,值为true
212-
const key = pair.trim();
213-
if (key) $arguments[key] = true;
214-
} else {
215-
// 有等号,分割键和值
216-
const key = pair.substring(0, equalIndex).trim();
217-
if (!key) continue;
218-
219-
let value;
220-
try {
221-
const encodedValue = pair.substring(equalIndex + 1);
222-
value = encodedValue ? safeDecodeURIComponent(encodedValue) : "";
223-
} catch (e) {
224-
value = pair.substring(equalIndex + 1) || "";
225-
}
226-
227-
$arguments[key] = value;
228-
}
167+
if (rawArgs.length > 2) {
168+
for (const pair of rawArgs[2].split('&')) {
169+
const key = pair.split('=')[0];
170+
const value = pair.split('=')[1];
171+
// 部分兼容之前的逻辑 const value = pair.split('=')[1] || true;
172+
otherArguments[key] =
173+
value == null || value === ''
174+
? true
175+
: decodeURIComponent(value);
229176
}
177+
noCache = otherArguments?.noCache;
178+
insecure = otherArguments?.insecure;
179+
} else if ($arguments?.noCache != null || $arguments?.insecure != null) {
180+
noCache = $arguments?.noCache;
181+
insecure = $arguments?.insecure;
230182
}
231183
} catch (e) {
232-
console.error("Failed to parse URL parameters:", e);
233-
$arguments = {};
184+
console.error("Failed to parse additional URL parameters:", e);
234185
}
235186
236187
return {
237-
url: baseUrl,
188+
url: url.split('#')[0],
238189
arguments: $arguments,
239190
noCache,
191+
insecure,
240192
};
241193
};
242194
243-
const buildUrlWithParams = (baseUrl, args, noCache) => {
244-
if (!baseUrl) return noCache ? "#noCache" : "";
195+
const buildUrlWithParams = (baseUrl, args, noCache, insecure) => {
196+
if (!baseUrl) {
197+
if(noCache && insecure){
198+
return "##noCache&insecure"
199+
}else if(noCache){
200+
return "##noCache"
201+
}else if(insecure){
202+
return "##insecure"
203+
} else {
204+
return ""
205+
}
206+
}
245207
246208
const validArgs = args && typeof args === "object" && Object.keys(args).length > 0;
247209
248210
// 如果没有参数且不需要noCache,直接返回baseUrl
249-
if (!validArgs && !noCache) return baseUrl;
211+
if (!validArgs && !noCache && !insecure) return baseUrl;
250212
251213
let paramStrings = [];
252214
@@ -275,8 +237,12 @@ const buildUrlWithParams = (baseUrl, args, noCache) => {
275237
}
276238
277239
// noCache 标记始终放在末尾
278-
if (noCache) {
240+
if (noCache && insecure) {
241+
result += "#noCache&insecure";
242+
}else if (noCache) {
279243
result += "#noCache";
244+
}else if (insecure) {
245+
result += "#insecure";
280246
}
281247
282248
return result;
@@ -307,6 +273,16 @@ const showNoCacheTips = () => {
307273
closeOnClickOverlay: true,
308274
});
309275
};
276+
const showInsecureTips = () => {
277+
Dialog({
278+
title: t(`editorPage.subConfig.nodeActions['${type}'].helpTitle`),
279+
content: t(`editorPage.subConfig.nodeActions['${type}'].insecureTips`),
280+
popClass: "auto-dialog",
281+
okText: "OK",
282+
noCancelBtn: true,
283+
closeOnClickOverlay: true,
284+
});
285+
};
310286
311287
// 显示参数编辑提示
312288
const showParamsEditTips = () => {
@@ -329,6 +305,7 @@ const handleLinkValueChange = () => {
329305
// 更新URL和noCache状态
330306
params.url = parsedParams.url;
331307
params.noCache = parsedParams.noCache;
308+
params.insecure = parsedParams.insecure;
332309
333310
// 更新arguments对象
334311
params.arguments = parsedParams.arguments || {};
@@ -447,6 +424,7 @@ onMounted(() => {
447424
params.url = parsedParams.url;
448425
params.arguments = parsedParams.arguments;
449426
params.noCache = parsedParams.noCache;
427+
params.insecure = parsedParams.insecure;
450428
paramsArguments.value = Object.entries(params.arguments).map(
451429
([key, value]) => ({ key, value }),
452430
);
@@ -469,6 +447,7 @@ watch(
469447
params.url,
470448
params.arguments,
471449
params.noCache,
450+
params.insecure,
472451
);
473452
}
474453
const item = form.process.find((item) => item.id === id);
@@ -498,6 +477,7 @@ watch(value, () => {
498477
params.url = parsedParams.url;
499478
params.arguments = parsedParams.arguments;
500479
params.noCache = parsedParams.noCache;
480+
params.insecure = parsedParams.insecure;
501481
502482
if (!isEditKeyValue.value) {
503483
paramsArguments.value = Object.entries(params.arguments).map(
@@ -516,6 +496,20 @@ watch(
516496
params.url,
517497
params.arguments,
518498
newValue,
499+
params.insecure,
500+
);
501+
}
502+
},
503+
);
504+
watch(
505+
() => params.insecure,
506+
(newValue) => {
507+
if (value.mode === "link") {
508+
value.content = buildUrlWithParams(
509+
params.url,
510+
params.arguments,
511+
params.noCache,
512+
newValue,
519513
);
520514
}
521515
},
@@ -529,6 +523,7 @@ watch(
529523
newValue,
530524
params.arguments,
531525
params.noCache,
526+
params.insecure,
532527
);
533528
}
534529
},

0 commit comments

Comments
 (0)