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+ < title > JSONP Example</ title >
7+ <!-- 引入 CryptoJS 库 -->
8+ < script src ="https://cdnjs.cloudflare.com/ajax/libs/crypto-js/4.1.1/crypto-js.min.js "> </ script >
9+ < style >
10+ /* 全局样式 */
11+ body {
12+ margin : 0 ;
13+ height : 100vh ;
14+ display : flex;
15+ justify-content : center;
16+ align-items : center;
17+ font-family : 'Segoe UI' , Tahoma, Geneva, Verdana, sans-serif;
18+ background : linear-gradient (135deg , # e6f4ff, # b3d9ff ); /* 浅蓝色渐变背景 */
19+ color : # 333 ; /* 深色文字 */
20+ overflow : hidden;
21+ }
22+
23+ /* 卡片式容器 */
24+ .card {
25+ background : rgba (255 , 255 , 255 , 0.8 ); /* 半透明白色背景 */
26+ backdrop-filter : blur (10px ); /* 毛玻璃效果 */
27+ border-radius : 15px ;
28+ padding : 2rem ;
29+ width : 100% ;
30+ max-width : 400px ;
31+ box-shadow : 0 8px 32px rgba (0 , 0 , 0 , 0.1 );
32+ border : 1px solid rgba (255 , 255 , 255 , 0.2 );
33+ text-align : center;
34+ transition : transform 0.3s ease, box-shadow 0.3s ease;
35+ }
36+
37+ .card : hover {
38+ transform : translateY (-5px ); /* 悬停时上移 */
39+ box-shadow : 0 12px 40px rgba (0 , 0 , 0 , 0.2 ); /* 悬停时阴影加深 */
40+ }
41+
42+ /* 标题 */
43+ h1 {
44+ margin : 0 0 1.5rem ;
45+ font-size : 1.8rem ;
46+ font-weight : 600 ;
47+ color : # 0077b6 ; /* 冷色系蓝色 */
48+ }
49+
50+ /* 按钮 */
51+ button {
52+ padding : 0.75rem 1.5rem ;
53+ font-size : 1rem ;
54+ border : none;
55+ border-radius : 8px ;
56+ background : # 0077b6 ; /* 冷色系蓝色 */
57+ color : # fff ; /* 白色文字 */
58+ cursor : pointer;
59+ transition : background 0.3s ease;
60+ }
61+
62+ button : hover {
63+ background : # 005f8a ; /* 悬停时稍暗的蓝色 */
64+ }
65+
66+ /* 结果展示 */
67+ # result {
68+ margin-top : 1.5rem ;
69+ padding : 1rem ;
70+ background : rgba (255 , 255 , 255 , 0.9 ); /* 半透明白色背景 */
71+ border-radius : 8px ;
72+ font-size : 1rem ;
73+ color : # 333 ; /* 深色文字 */
74+ word-wrap : break-word;
75+ overflow-y : auto;
76+ max-height : 200px ;
77+ border : 1px solid rgba (255 , 255 , 255 , 0.2 );
78+ }
79+
80+ /* 加载动画 */
81+ .loader {
82+ display : none; /* 默认隐藏 */
83+ border : 4px solid rgba (0 , 119 , 182 , 0.3 ); /* 冷色系蓝色 */
84+ border-top : 4px solid # 0077b6 ; /* 冷色系蓝色 */
85+ border-radius : 50% ;
86+ width : 30px ;
87+ height : 30px ;
88+ animation : spin 1s linear infinite;
89+ margin : 1rem auto;
90+ }
91+
92+ @keyframes spin {
93+ 0% { transform : rotate (0deg ); }
94+ 100% { transform : rotate (360deg ); }
95+ }
96+ </ style >
97+ </ head >
98+ < body >
99+ < div class ="card ">
100+ < h1 > JSONP Example</ h1 >
101+ < button id ="fetchButton "> 发送请求</ button >
102+ < div id ="result "> 点击按钮发送请求...</ div >
103+ < div class ="loader " id ="loader "> </ div >
104+ </ div >
105+
106+ < script >
107+ // 加密密钥(与后端一致)
108+ const SECRET_KEY = 'CC11001100' ;
109+
110+ // 加密函数(使用 RC4)
111+ function encryptData ( data ) {
112+ return CryptoJS . RC4 . encrypt ( JSON . stringify ( data ) , SECRET_KEY ) . toString ( ) ;
113+ }
114+
115+ // 解密函数(使用 Rabbit)
116+ function decryptData ( encryptedData ) {
117+ try {
118+ const bytes = CryptoJS . Rabbit . decrypt ( encryptedData , SECRET_KEY ) ;
119+ const decryptedText = bytes . toString ( CryptoJS . enc . Utf8 ) ;
120+
121+ if ( ! decryptedText ) {
122+ throw new Error ( '解密失败:无效的密钥或数据' ) ;
123+ }
124+
125+ return decryptedText ;
126+ } catch ( error ) {
127+ console . error ( '解密失败:' , error . message ) ;
128+ return null ;
129+ }
130+ }
131+
132+ // JSONP 请求
133+ function fetchData ( ) {
134+ const data = { name : 'CC11001100' } ;
135+ const encryptedData = encryptData ( data ) ;
136+
137+ // 显示加载动画
138+ const loader = document . getElementById ( 'loader' ) ;
139+ const resultDiv = document . getElementById ( 'result' ) ;
140+ loader . style . display = 'block' ;
141+ resultDiv . innerText = '加载中...' ;
142+
143+ const script = document . createElement ( 'script' ) ;
144+ script . src = `http://localhost:3000/api/data?encryptedData=${ encodeURIComponent ( encryptedData ) } &callback=handleResponse` ;
145+ document . body . appendChild ( script ) ;
146+ }
147+
148+ // 处理 JSONP 响应
149+ function handleResponse ( encryptedResponse ) {
150+ const decryptedResponse = decryptData ( encryptedResponse ) ;
151+
152+ // 隐藏加载动画
153+ const loader = document . getElementById ( 'loader' ) ;
154+ const resultDiv = document . getElementById ( 'result' ) ;
155+ loader . style . display = 'none' ;
156+
157+ if ( ! decryptedResponse ) {
158+ resultDiv . innerText = '解密失败:无效的密钥或数据' ;
159+ return ;
160+ }
161+
162+ const responseData = JSON . parse ( decryptedResponse ) ;
163+ resultDiv . innerText = responseData . message ;
164+ }
165+
166+ // 绑定按钮点击事件
167+ document . getElementById ( 'fetchButton' ) . addEventListener ( 'click' , function ( ) {
168+ fetchData ( ) ;
169+ } ) ;
170+ </ script >
171+ </ body >
172+ </ html >
0 commit comments