websocket测试页面.html 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625
  1. <html>
  2. <head>
  3. <meta charset=UTF-8">
  4. <title>WebSocket读卡测试</title>
  5. </head>
  6. <body bgcolor="#D2F0FF">
  7. <h1 style="text-align:center;color:#5555FF;">身份证阅读器WebSocket接入测试页面</h1>
  8. <input id="url" type="text" value="ws://127.0.0.1:18890" style="width:500px"/>
  9. <button onclick="openWebSocket()">打开WebSocket连接</button>
  10. <button onclick="closeWebSocket()">关闭WebSocket连接</button>
  11. <h3>当前消息</h3>
  12. <button onclick="clearMsg()">清除</button>
  13. <div id="message"></div>
  14. </br>
  15. <table border="0" width="50%" cellpadding="0" cellspacing="0" style="padding-left:100px;">
  16. <tr>
  17. <td><input type="button" value="连接设备" onclick="connect()"></td>
  18. <td><input type="button" value="状态" onclick="getStatus()"></td>
  19. <td><input type="button" value="读卡(不合成照片)" onclick="readCard()"></td>
  20. <td><input type="button" value="读卡(合成照片)" onclick="readCert()"></td>
  21. <td><input type="button" value="断开" onclick="disconnect()"></td>
  22. <td><input type="button" value="读IC卡序列号" onclick="readICCardSN()"></td>
  23. <td><input type="button" value="读身份证物理卡号" onclick="readIDCardSN()"></td>
  24. <td><input type="button" value="读安全模块号" onclick="getSAMID()"></td>
  25. <td><input type="button" value="开启推送(带图片)" onclick="startPushInfosWithImg()"></td>
  26. <td><input type="button" value="开启推送(不带图片)" onclick="startPushInfosWithOutImg()"></td>
  27. <td><input type="button" value="关闭推送" onclick="stopPushInfos()"></td>
  28. <td><input type="button" value="允许重复读卡" onclick="enableRepeatRead()"></td>
  29. <td><input type="button" value="禁止重复读卡" onclick="disableRepeatRead()"></td>
  30. <td><input type="button" value="关闭读卡提示音" onclick="Routon_Mute()"></td>
  31. <td><input type="button" value="开启读卡提示音" onclick="Routon_UnMute()"></td>
  32. <td><input type="button" value="开启连接状态检测" onclick="startCheckStatus()"></td>
  33. <td><input type="button" value="关闭连接状态检测" onclick="stopCheckStatus()"></td>
  34. </tr>
  35. </table>
  36. <br/>
  37. <table border="0" width="100%" cellpadding="0" cellspacing="10">
  38. <tr>
  39. <td align="right">读卡时间:</td>
  40. <td><input type="text" id="timeElapsed" size="49" style="width:400px;" readonly="readonly"></td>
  41. </tr>
  42. <tr>
  43. <td align="right">数字签名:</td>
  44. <td><input type="text" id="signature" size="49" style="width:400px;" readonly="readonly"></td>
  45. </tr>
  46. <tr>
  47. <td align="right">厂家标识:</td>
  48. <td><input type="text" id="venderId" size="49" style="width:400px;" readonly="readonly"></td>
  49. </tr>
  50. <td align="right">卡类型:</td>
  51. <td><input type="text" id="certType" size="49" style="width:400px;" readonly="readonly">(1-中国居民身份证,50-外国人永久居住证证,54-台湾居住证,55-港澳居住证)
  52. </td>
  53. </tr>
  54. <tr>
  55. <td align="right">中/英姓名:</td>
  56. <td><input type="text" id="partyName" size="49" style="width:400px;" readonly="readonly">(要求中间,两头都没有空格)</td>
  57. </tr>
  58. <tr>
  59. <td align="right">性别:</td>
  60. <td><input type="text" id="gender" size="49" style="width:400px;" readonly="readonly">(取值为“1”(表示“男”)或“0”(表示“女”))
  61. </td>
  62. </tr>
  63. <tr>
  64. <td align="right">民族/国籍:</td>
  65. <td><input type="text" id="nation" size="49" style="width:400px;" readonly="readonly">(汉字即可)</td>
  66. </tr>
  67. <tr>
  68. <td align="right">出生日期:</td>
  69. <td><input type="text" id="bornDay" size="49" style="width:400px;" readonly="readonly">(要求格式为:yyyyMMdd,长度为8)
  70. </td>
  71. </tr>
  72. <tr>
  73. <td align="right">住址:</td>
  74. <td><input type="text" id="certAddress" size="49" style="width:400px;" readonly="readonly">(外国人永久居留身份证地址为“空”)
  75. </td>
  76. </tr>
  77. <tr>
  78. <td align="right">身份证号:</td>
  79. <td><input type="text" id="certNumber" size="49" style="color:#FF0000;width:400px;" readonly="readonly">(居民身份号码,长度18位)
  80. </td>
  81. </tr>
  82. <tr>
  83. <td align="right">签发机关:</td>
  84. <td><input type="text" id="certOrg" size="49" style="width:400px;" readonly="readonly">(外国永久居留身份证签发机关为“机关代码”)
  85. </td>
  86. </tr>
  87. <tr>
  88. <td align="right">开始期限:</td>
  89. <td><input type="text" id="effDate" size="49" style="width:400px;" readonly="readonly">(要求格式为:yyyyMMdd,长度为8)
  90. </td>
  91. </tr>
  92. <tr>
  93. <td align="right">结束期限:</td>
  94. <td><input type="text" id="expDate" size="49" style="width:400px;" readonly="readonly">(要求格式为:yyyyMMdd,长度为8,或者是“长期”)
  95. </td>
  96. </tr>
  97. <tr>
  98. <td align="right">照片:</td>
  99. <td><img id="HeadPic" style="height: 126px; width: 102px" align="top" />
  100. </tr>
  101. <tr>
  102. <td>预览:</td>
  103. <td><img id="PhotoDisplay" style="width:341px; height:443px;"/></td>
  104. <td>正面:</td>
  105. <td><img id="FrontPic" style="width:341px; height:222px;"/></td>
  106. <td>背面:</td>
  107. <td><img id="BackPic" style="width:341px; height:222px;"/></td>
  108. </tr>
  109. </table>
  110. <br>
  111. <br>
  112. <table border="0" width="100%" cellpadding="0" cellspacing="10">
  113. <tr>
  114. <!--td align="right"">扇区号:</td>
  115. <td><input type="text" id="sid" size="49" style="width:50px;"></td>
  116. <td align="right">块号:</td>
  117. <td><input type="text" id="bid" size="49" style="width:50px;"></td>
  118. <td align="right">密钥类型:</td>
  119. <td><input type="text" id="keyType" size="49" style="width:50px;"></td>
  120. <td align="right">密钥:</td>
  121. <td><input type="text" id="key" size="49" style="width:100px;"></td-->
  122. <td>
  123. 扇区号(SID):<input type="text" style="width:60px;hidth:30px" id="input_sid" onkeyup="value=value.replace(/\D/g,'')" oncontextmenu="return false;" onblur="valid('input_sid',15)">
  124. 块号(BID):<input type="text" style="width:60px;hidth:30px" id="input_bid" onkeyup="value=value.replace(/\D/g,'')" oncontextmenu="return false;" onblur="valid('input_bid',3)">
  125. 秘钥类型(KeyType 1-keyA&nbsp;2-keyB):<input type="text" id="input_keytype" onkeyup="value=value.replace(/\D/g,'')" oncontextmenu="return false;" onblur="valid('input_keytype',2)">
  126. 秘钥(Key):<input type="text" id="input_key">
  127. </td>
  128. </tr>
  129. <tr>
  130. <td >指令:<input type="text" id="cmd" size="49" style="width:400px;"></td>
  131. </tr>
  132. <tr>
  133. <td>结果:<textarea id="ACardResult" rows="8" cols="47" style="width:400px;" readonly="readonly"></textarea></td>
  134. </tr>
  135. </table>
  136. <table border="0" width="100%" cellpadding="0" cellspacing="10">
  137. <tr>
  138. <!--td><input type="button" value="读M1卡" onclick="readM1Card()"></td>
  139. <td><input type="button" value="写M1卡" onclick="writeM1Card()"></td>
  140. <td><input type="button" value="发送APDU指令" onclick="handleAPDUCMD()"></td-->
  141. <td>
  142. <input type="button" value="读M1卡" onclick="readM1Card()">
  143. <input type="button" value="写M1卡" onclick="writeM1Card()">
  144. <input type="button" value="发送APDU指令" onclick="handleAPDUCMD()">
  145. </td>
  146. </tr>
  147. </table>
  148. </body>
  149. <script src="res/jquery.min.js"></script>
  150. <script src="res/socket.js"></script>
  151. <script type="text/javascript">
  152. //清空页面上显示的内容
  153. function clearForm() {
  154. //对应控件的值全部清空
  155. document.getElementById("timeElapsed").value = "";
  156. document.getElementById("certType").value = "";
  157. document.getElementById("timeElapsed").value = "";
  158. document.getElementById("venderId").value = "";
  159. document.getElementById("signature").value = "";
  160. document.getElementById("partyName").value = "";
  161. document.getElementById("gender").value = "";
  162. document.getElementById("nation").value = "";
  163. document.getElementById("bornDay").value = "";
  164. document.getElementById("certAddress").value = "";
  165. document.getElementById("certNumber").value = "";
  166. document.getElementById("certOrg").value = "";
  167. document.getElementById("effDate").value = "";
  168. document.getElementById("expDate").value = "";
  169. document.getElementById("HeadPic").src = "";
  170. document.getElementById("PhotoDisplay").src = "";
  171. document.getElementById("FrontPic").src = "";
  172. document.getElementById("BackPic").src = "";
  173. }
  174. // 清除窗口消息
  175. function clearMsg(){
  176. document.getElementById('message').innerHTML = "";
  177. clearForm();
  178. }
  179. var websocket = null;
  180. //监听窗口关闭事件,当窗口关闭时,主动去关闭websocket连接,防止连接还没断开就关闭窗口,server端会抛异常。
  181. window.onbeforeunload = function () {
  182. closeWebSocket();
  183. };
  184. // 连接服务端
  185. function openWebSocket(){
  186. var url = document.getElementById('url').value;
  187. //var token = document.getElementById('token').value;
  188. if('WebSocket' in window) {
  189. //websocket = new WebSocket(url,[token]);
  190. websocket = new WebSocket(url);
  191. } else if('MozWebSocket' in window) {
  192. console.log("MozWebSocket");
  193. websocket = new MozWebSocket(url);
  194. } else {
  195. console.log("SockJS");
  196. //websocket = new SockJS("localhost:8088/websocket/webSocketByTomcat/"+document.getElementById('sessionId').value);
  197. }
  198. if(websocket == null)
  199. {
  200. alert("创建WebSocket对象失败");
  201. }
  202. //连接发生错误的回调方法
  203. websocket.onerror = function () {
  204. setMessageInnerHTML("WebSocket连接发生错误");
  205. };
  206. //连接成功建立的回调方法
  207. websocket.onopen = function () {
  208. setMessageInnerHTML("WebSocket连接成功");
  209. };
  210. //接收到消息的回调方法
  211. websocket.onmessage = function (event) {
  212. setMessageInnerHTML(event.data);
  213. var resultObj = eval('(' +event.data+')');
  214. //resultFlag为0代表读卡成功
  215. if (resultObj.name == "readCard" || resultObj.name == "readCert"
  216. || resultObj.name == "PushWithImg" || resultObj.name == "PushWithOutImg")
  217. {
  218. if (resultObj.resultFlag == "0") {
  219. //回显相关数据
  220. document.getElementById("signature").value = resultObj.signature;
  221. document.getElementById("venderId").value = resultObj.venderId;
  222. document.getElementById("certType").value = resultObj.resultContent.certType;
  223. document.getElementById("partyName").value = resultObj.resultContent.partyName;
  224. document.getElementById("gender").value = resultObj.resultContent.gender;
  225. document.getElementById("nation").value = resultObj.resultContent.nation;
  226. document.getElementById("bornDay").value = resultObj.resultContent.bornDay;
  227. document.getElementById("certAddress").value = resultObj.resultContent.certAddress;
  228. document.getElementById("certNumber").value = resultObj.resultContent.certNumber;
  229. document.getElementById("certOrg").value = resultObj.resultContent.certOrg;
  230. document.getElementById("effDate").value = resultObj.resultContent.effDate;
  231. document.getElementById("expDate").value = resultObj.resultContent.expDate;
  232. document.getElementById("HeadPic").src = "data:image/jpeg;base64," + resultObj.resultContent.identityPic;
  233. if (resultObj.name == "readCert" || resultObj.name == "PushWithImg")
  234. {
  235. document.getElementById("PhotoDisplay").src = "data:image/jpeg;base64," + resultObj.resultContent.identityPrintPic;
  236. document.getElementById("FrontPic").src = "data:image/jpeg;base64," + resultObj.resultContent.identityFrontPic;
  237. document.getElementById("BackPic").src = "data:image/jpeg;base64," + resultObj.resultContent.identityBackPic;
  238. }
  239. } else if (resultObj.resultFlag == "-1") {
  240. if (resultObj.errorMsg == "端口打开失败") {
  241. //alert("读卡器未连接");
  242. } else {
  243. //alert(resultObj.errorMsg);
  244. }
  245. } else if (resultObj.resultFlag == "-2") {
  246. //alert(resultObj.errorMsg);
  247. }
  248. }
  249. else if (resultObj.name == "getStatus")
  250. {
  251. if (resultObj.resultFlag == "0")
  252. {
  253. if (resultObj.status == "0")
  254. {
  255. }
  256. else
  257. {
  258. alert("设备连接已断开,请检查读卡器连接");
  259. }
  260. }
  261. }
  262. else if (resultObj.name == "readM1Card" || resultObj.name == "writeM1Card" || resultObj.name == "handleAPDUCMD") {
  263. document.getElementById("ACardResult").value = event.data;
  264. }
  265. };
  266. //连接关闭的回调方法
  267. websocket.onclose = function () {
  268. setMessageInnerHTML("WebSocket连接关闭");
  269. };
  270. }
  271. //将消息显示在网页上
  272. function setMessageInnerHTML(text) {
  273. document.getElementById('message').innerHTML = text;
  274. }
  275. //关闭WebSocket连接
  276. function closeWebSocket() {
  277. websocket.close();
  278. }
  279. var timer = 0;
  280. function checkStatus()
  281. {
  282. var jsonObj = {
  283. "name":"getStatus"
  284. };
  285. var jStr = JSON.stringify(jsonObj);
  286. websocket.send(jStr);
  287. }
  288. // 开始定时检测连接
  289. function startCheckStatus(){
  290. timer = setInterval(checkStatus, 5000);
  291. }
  292. function stopCheckStatus(){
  293. clearInterval(timer);
  294. timer = 0;
  295. }
  296. //连接设备
  297. function connect()
  298. {
  299. var jsonObj = {
  300. "name":"connect"
  301. };
  302. var jStr = JSON.stringify(jsonObj);
  303. websocket.send(jStr);
  304. }
  305. //断开设备连接
  306. function disconnect()
  307. {
  308. var jsonObj = {
  309. "name":"disconnect"
  310. };
  311. var jStr = JSON.stringify(jsonObj);
  312. websocket.send(jStr);
  313. }
  314. //获取状态
  315. function getStatus()
  316. {
  317. var jsonObj = {
  318. "name":"getStatus"
  319. };
  320. var jStr = JSON.stringify(jsonObj);
  321. websocket.send(jStr);
  322. }
  323. //读卡
  324. function readCard()
  325. {
  326. var jsonObj = {
  327. "name":"readCard"
  328. };
  329. var jStr = JSON.stringify(jsonObj);
  330. websocket.send(jStr);
  331. }
  332. //读卡
  333. function readCert()
  334. {
  335. var jsonObj = {
  336. "name":"readCert"
  337. };
  338. var jStr = JSON.stringify(jsonObj);
  339. websocket.send(jStr);
  340. }
  341. //获取IC卡序列号
  342. function readICCardSN()
  343. {
  344. var jsonObj = {
  345. "name":"readICCardSN"
  346. };
  347. var jStr = JSON.stringify(jsonObj);
  348. websocket.send(jStr);
  349. }
  350. //获取身份证物理卡号
  351. function readIDCardSN()
  352. {
  353. var jsonObj = {
  354. "name":"readIDCardSN"
  355. };
  356. var jStr = JSON.stringify(jsonObj);
  357. websocket.send(jStr);
  358. }
  359. //获取SAMID
  360. function getSAMID()
  361. {
  362. var jsonObj = {
  363. "name":"getSAMID"
  364. };
  365. var jStr = JSON.stringify(jsonObj);
  366. websocket.send(jStr);
  367. }
  368. // 获取版本号
  369. function getVersion()
  370. {
  371. var jsonObj = {
  372. "name":"getVersion"
  373. };
  374. var jStr = JSON.stringify(jsonObj);
  375. websocket.send(jStr);
  376. }
  377. //开启推送(带图片)
  378. function startPushInfosWithImg()
  379. {
  380. var jsonObj = {
  381. "name":"openPush",
  382. "withImg": true
  383. };
  384. var jStr = JSON.stringify(jsonObj);
  385. websocket.send(jStr);
  386. }
  387. //开启推送(不带图片)
  388. function startPushInfosWithOutImg()
  389. {
  390. var jsonObj = {
  391. "name":"openPush",
  392. "withImg": false,
  393. };
  394. var jStr = JSON.stringify(jsonObj);
  395. websocket.send(jStr);
  396. }
  397. //关闭推送
  398. function stopPushInfos()
  399. {
  400. var jsonObj = {
  401. "name":"closePush"
  402. };
  403. var jStr = JSON.stringify(jsonObj);
  404. websocket.send(jStr);
  405. }
  406. // 允许重复读卡
  407. function enableRepeatRead() {
  408. var jsonObj = {
  409. "name":"repeatRead",
  410. "isRepeatRead": true
  411. };
  412. var jStr = JSON.stringify(jsonObj);
  413. websocket.send(jStr);
  414. }
  415. // 禁止重复读卡
  416. function disableRepeatRead() {
  417. var jsonObj = {
  418. "name":"repeatRead",
  419. "isRepeatRead": false
  420. };
  421. var jStr = JSON.stringify(jsonObj);
  422. websocket.send(jStr);
  423. }
  424. // 开启静音
  425. function Routon_Mute() {
  426. var jsonObj = {
  427. "name":"mute",
  428. "isMute": true
  429. };
  430. var jStr = JSON.stringify(jsonObj);
  431. websocket.send(jStr);
  432. }
  433. // 关闭静音
  434. function Routon_UnMute() {
  435. var jsonObj = {
  436. "name":"mute",
  437. "isMute": false
  438. };
  439. var jStr = JSON.stringify(jsonObj);
  440. websocket.send(jStr);
  441. }
  442. //读M1卡扇区内容
  443. function readM1Card() {
  444. var result = "";
  445. var sid = "1";
  446. var bid = "1";
  447. var keyType = "1";
  448. var key = "ffffffffffff";
  449. if(document.getElementById("input_sid").value != "")
  450. {
  451. sid = document.getElementById("input_sid").value;
  452. }
  453. if(document.getElementById("input_bid").value != "")
  454. {
  455. bid = document.getElementById("input_bid").value;
  456. }
  457. if(document.getElementById("input_keytype").value != "")
  458. {
  459. keyType = document.getElementById("input_keytype").value;
  460. }
  461. if(document.getElementById("input_key").value != "")
  462. {
  463. key = document.getElementById("input_key").value;
  464. }
  465. var jsonObj = {
  466. "name":"readM1Card",
  467. "params": {
  468. "SID": sid,
  469. "BID": bid,
  470. "KEYTYPE": keyType,
  471. "KEY": key
  472. }
  473. };
  474. var jStr = JSON.stringify(jsonObj);
  475. websocket.send(jStr);
  476. }
  477. //写M1卡扇区内容
  478. function writeM1Card() {
  479. var result = "";
  480. var sid = "1";
  481. var bid = "1";
  482. var keyType = "1";
  483. var key = "ffffffffffff";
  484. var data = "00000000000000000000000000000000";
  485. if(document.getElementById("input_sid").value != "")
  486. {
  487. sid = document.getElementById("input_sid").value;
  488. }
  489. if(document.getElementById("input_bid").value != "")
  490. {
  491. bid = document.getElementById("input_bid").value;
  492. }
  493. if(document.getElementById("input_keytype").value != "")
  494. {
  495. keyType = document.getElementById("input_keytype").value;
  496. }
  497. if(document.getElementById("input_key").value != "")
  498. {
  499. key = document.getElementById("input_key").value;
  500. }
  501. if(document.getElementById("cmd").value != "")
  502. {
  503. data = document.getElementById("cmd").value;
  504. }
  505. var jsonObj = {
  506. "name":"writeM1Card",
  507. "params": {
  508. "SID": sid,
  509. "BID": bid,
  510. "KEYTYPE": keyType,
  511. "KEY": key,
  512. "DATA": data
  513. }
  514. };
  515. var jStr = JSON.stringify(jsonObj);
  516. websocket.send(jStr);
  517. }
  518. //处理CPU卡APDU指令
  519. function handleAPDUCMD(){
  520. //var cmd = "00A4000000"; //基本命令(测试用):选择MF下的根目录,返回值为:6F15840E315041592E5359532E4444463031A5038801019000
  521. var cmd = "";
  522. if(document.getElementById("cmd").value != "")
  523. {
  524. cmd = document.getElementById("cmd").value;
  525. }
  526. var jsonObj = {
  527. "name":"handleAPDUCMD",
  528. "params": {
  529. "APDUCMD": cmd
  530. }
  531. };
  532. var jStr = JSON.stringify(jsonObj);
  533. websocket.send(jStr);
  534. }
  535. </script>
  536. </html>