PageSourceSearch

http://www.nationalmuseum.cn/static/modules/cms/js/public.js

js nationalmuseum.cn collected 2026-09-25 01:19:04 UTC 10,393 bytes, 357 lines download raw bytes

1<!DOCTYPE html>
2<html lang="en">
3<head>
4  <meta charset="UTF-8" />
5  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
6  <meta http-equiv="Cache-Control" content="no-store, no-cache, must-revalidate, max-age=0" />
7  <meta http-equiv="Pragma" content="no-cache" />
8  <meta http-equiv="Expires" content="0" />
9  <title id="page-title">进行验证</title>
10
11  <style>
12    html, body {
13      width: 100%;
14      height: 100%;
15      padding: 0;
16      margin: 0;
17      color: #3C3C3C;
18      background: #EBF3FB;
19      display: flex;
20      flex-direction: column;
21      align-items: center;
22      justify-content: center;
23      min-height: 100vh;
24    }
25
26    .container {
27      display: flex;
28      flex-direction: column;
29      align-items: center;
30      justify-content: center;
31      padding: 40px 0;
32    }
33
34    .lang-switch {
35      position: absolute;
36      top: 10px;
37      right: 10px;
38      background: #fff;
39      border: 1px solid #ddd;
40      border-radius: 4px;
41      padding: 5px 10px;
42      cursor: pointer;
43      font-size: 14px;
44      color: #3C3C3C;
45    }
46
47    .lang-switch:hover {
48      background: #f5f5f5;
49    }
50
51    .success-message {
52      color: #5eaa2f;
53      text-align: center;
54      font-size: 18px;
55      margin-top: 20px;
56      font-family: system, -apple-system, "BlinkMacSystemFont",
57      ".SFNSText-Regular", "San Francisco", "Roboto", "Segoe UI",
58      "Helvetica Neue", "Lucida Grande", "Ubuntu", "arial", sans-serif;
59    }
60
61    .error-message {
62      color: #ed4630;
63      text-align: center;
64      font-size: 16px;
65      margin-top: 20px;
66      font-family: system, -apple-system, "BlinkMacSystemFont",
67      ".SFNSText-Regular", "San Francisco", "Roboto", "Segoe UI",
68      "Helvetica Neue", "Lucida Grande", "Ubuntu", "arial", sans-serif;
69    }
70
71    /* Toast样式 */
72    .toast {
73      position: fixed;
74      top: 50%;
75      left: 50%;
76      transform: translate(-50%, -50%);
77      padding: 12px 24px;
78      border-radius: 6px;
79      font-size: 14px;
80      z-index: 1000;
81      opacity: 0;
82      transition: opacity 0.3s ease;
83    }
84
85    .toast.show {
86      opacity: 1;
87    }
88
89    .toast.success {
90      background: #f0f9eb;
91      border: 1px solid #dcf9cc;
92      color: #5eaa2f;
93      box-shadow: 1px 1px 10px #e0e0e0;
94    }
95
96    .toast.error {
97      background: #fef0f0;
98      border: 1px solid #fcd6d6;
99      color: #ed4630;
100      box-shadow: 1px 1px 10px #e0e0e0;
101    }
102  </style>
103</head>
104<body>
105<button id="lang-switch" class="lang-switch">English</button>
106
107<div class="container">
108  <!-- 添加提示信息区域 -->
109  <div class="info-message" id="info-message">
110    <h2 id="info-title">安全验证</h2>
111    <p id="info-text">为了确保您的访问安全,请完成以下验证</p>
112  </div>
113
114  <cap-widget
115          id="cap"
116          data-cap-api-endpoint="/_waf_nnlwvqab/"
117          data-cap-i18n-verifying-label="验证中..."
118          data-cap-i18n-initial-state="我是人类"
119          data-cap-i18n-solved-label="我是人类"
120          data-cap-i18n-error-label="错误"
121  ></cap-widget>
122</div>
123
124<script>
125  // 语言资源
126  const i18n = {
127    'zh': {
128      title: '进行验证',
129      verifySuccess: '验证成功,页面即将刷新...',
130      verifyFail: '验证失败',
131      validationError: '验证异常',
132      switchLang: 'English',
133      // 添加提示信息的中文翻译
134      infoTitle: '安全验证',
135      infoText: '为了确保您的访问安全,请完成以下验证',
136      // Cap.js widget 多语言
137      capWidget: {
138        verifyingLabel: '验证中...',
139        initialState: '我是人类',
140        solvedLabel: '我是人类',
141        errorLabel: '错误'
142      }
143    },
144    'en': {
145      title: 'Verification',
146      verifySuccess: 'Verification successful, page will refresh...',
147      verifyFail: 'Verification failed',
148      validationError: 'Validation error',
149      switchLang: '中文',
150      // 添加提示信息的英文翻译
151      infoTitle: 'Security Verification',
152      infoText: 'To ensure the security of your access, please complete the following verification',
153      // Cap.js widget 多语言
154      capWidget: {
155        verifyingLabel: 'Verifying...',
156        initialState: "I'm a human",
157        solvedLabel: "I'm a human",
158        errorLabel: 'Error'
159      }
160    }
161  };
162
163  // 语言管理
164  const langManager = (function() {
165    // Cookie 操作函数
166    function setCookie(name, value, days) {
167      let expires = "";
168      if (days) {
169        const date = new Date();
170        date.setTime(date.getTime() + (days * 24 * 60 * 60 * 1000));
171        expires = "; expires=" + date.toUTCString();
172      }
173      document.cookie = name + "=" + (value || "") + expires + "; path=/";
174    }
175
176    function getCookie(name) {
177      const nameEQ = name + "=";
178      const ca = document.cookie.split(';');
179      for(let i = 0; i < ca.length; i++) {
180        let c = ca[i];
181        while (c.charAt(0) === ' ') c = c.substring(1, c.length);
182        if (c.indexOf(nameEQ) === 0) return c.substring(nameEQ.length, c.length);
183      }
184      return null;
185    }
186
187    // 检测浏览器语言
188    function detectBrowserLang() {
189      const browserLang = navigator.language || navigator.userLanguage;
190      return browserLang.toLowerCase().startsWith('zh') ? 'zh' : 'en';
191    }
192
193    let currentLang = getCookie('samwaf_lang') || detectBrowserLang();
194
195    function setLanguage(lang) {
196      currentLang = lang;
197      setCookie('samwaf_lang', lang, 30); // 保存30天
198      applyLanguage();
199      return currentLang;
200    }
201
202    function getCurrentLang() {
203      return currentLang;
204    }
205
206    function getText(key) {
207      return i18n[currentLang][key] || i18n['en'][key] || key;
208    }
209
210    function getCapWidgetText(key) {
211      return i18n[currentLang].capWidget[key] || i18n['en'].capWidget[key] || key;
212    }
213
214    function applyLanguage() {
215      // 更新页面标题
216      document.getElementById('page-title').textContent = getText('title');
217      // 更新语言切换按钮
218      document.getElementById('lang-switch').textContent = getText('switchLang');
219
220      // 更新提示信息的多语言内容
221      const infoTitle = document.getElementById('info-title');
222      const infoText = document.getElementById('info-text');
223      if (infoTitle) {
224        infoTitle.textContent = getText('infoTitle');
225      }
226      if (infoText) {
227        infoText.textContent = getText('infoText');
228      }
229
230      // 更新cap-widget的多语言属性
231      const capWidget = document.getElementById('cap');
232      if (capWidget) {
233        capWidget.setAttribute('data-cap-i18n-verifying-label', getCapWidgetText('verifyingLabel'));
234        capWidget.setAttribute('data-cap-i18n-initial-state', getCapWidgetText('initialState'));
235        capWidget.setAttribute('data-cap-i18n-solved-label', getCapWidgetText('solvedLabel'));
236        capWidget.setAttribute('data-cap-i18n-error-label', getCapWidgetText('errorLabel'));
237      }
238    }
239
240    return {
241      setLanguage,
242      getCurrentLang,
243      getText,
244      getCapWidgetText,
245      applyLanguage
246    };
247  })();
248
249  // Toast提示函数
250  function showToast(message, type = 'success') {
251    // 移除已存在的toast
252    const existingToast = document.querySelector('.toast');
253    if (existingToast) {
254      existingToast.remove();
255    }
256
257    const toast = document.createElement('div');
258    toast.className = `toast ${type}`;
259    toast.textContent = message;
260    document.body.appendChild(toast);
261
262    // 显示toast
263    setTimeout(() => {
264      toast.classList.add('show');
265    }, 100);
266
267    // 隐藏toast
268    setTimeout(() => {
269      toast.classList.remove('show');
270      setTimeout(() => {
271        if (toast.parentNode) {
272          toast.parentNode.removeChild(toast);
273        }
274      }, 300);
275    }, 2000);
276  }
277
278  // 初始化语言
279  document.addEventListener('DOMContentLoaded', function() {
280    langManager.applyLanguage();
281  });
282
283  // 语言切换按钮事件
284  document.getElementById('lang-switch').addEventListener('click', function() {
285    const newLang = langManager.getCurrentLang() === 'zh' ? 'en' : 'zh';
286    langManager.setLanguage(newLang);
287    // 刷新页面以重新初始化验证码
288    window.location.reload();
289  });
290
291  // 动态获取当前页面的协议、域名和端口
292  const currentProtocol = window.location.protocol; // http: 或 https:
293  const currentHost = window.location.host; // 包含域名和端口
294  window.CAP_CUSTOM_WASM_URL = `${currentProtocol}//${currentHost}/_waf_nnlwvqab/cap_wasm.min.js`;
295</script>
296<script src="/_waf_nnlwvqab/widget.js"></script>
297
298<script>
299  const widget = document.querySelector("#cap");
300
301  widget.addEventListener("solve", function (e) {
302    const token = e.detail.token;
303    // console.log("Captcha solved!");
304    //console.log("Token:" + token); // Token is returned by the server
305
306    // Submit token to backend for validation
307    validateToken(token);
308  });
309
310  // Function to validate token with backend
311  async function validateToken(token) {
312    try {
313      const response = await fetch('/_waf_nnlwvqab/validate', {
314        method: 'POST',
315        headers: {
316          'Content-Type': 'application/json',
317        },
318        body: JSON.stringify({ token: token })
319      });
320
321      if (!response.ok) {
322        throw new Error(`HTTP error! status: ${response.status}`);
323      }
324
325      const result = await response.json();
326
327      if (result.success) {
328        // 隐藏验证码组件
329        document.querySelector('#cap').style.display = 'none';
330        // 隐藏语言切换按钮
331        document.getElementById('lang-switch').style.display = 'none';
332
333        // 显示成功消息
334        const successEl = document.createElement("div");
335        successEl.className = "success-message";
336        successEl.textContent = langManager.getText('verifySuccess');
337        document.querySelector(".container").appendChild(successEl);
338
339        // 显示成功toast
340        showToast(langManager.getText('verifySuccess'), 'success');
341
342        // 2秒后刷新页面
343        setTimeout(() => {
344          window.location.reload();
345        }, 2000);
346      } else {
347        // 显示失败toast
348        showToast(langManager.getText('verifyFail'), 'error');
349      }
350    } catch (error) {
351      console.error('Validation error:', error);
352      // 显示错误toast
353      showToast(langManager.getText('validationError') + ': ' + error.message, 'error');
354    }
355  }
356</script>
357</html>

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.