Captcha.vue 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285
  1. <template>
  2. <div id="captcha_div"></div>
  3. </template>
  4. <script>
  5. import '@/assets/css/captcha.css'
  6. var captcha = {};
  7. export default {
  8. name: 'Captcha',
  9. methods: {
  10. initCaptcha(param, success, failure){
  11. param.path="/"
  12. if(param.type == 3){
  13. var that = this;
  14. param.widthInt = parseInt(param.width);
  15. param.zoomRate = 315/param.widthInt;
  16. param.heightInt = parseInt(196/param.zoomRate);
  17. param.height = param.heightInt + "px";
  18. param.fragWidth = parseInt(33/param.zoomRate) + "px";
  19. param.bgSize = parseInt((315+33)/param.zoomRate) + "px";
  20. console.log("width:"+param.widthInt+"|zoomRate:"+param.zoomRate+"|heightInt:"+param.heightInt);
  21. captcha = {
  22. conf : param, // json
  23. data:null,
  24. loaded : false,
  25. captchaSlider : {
  26. e : null,
  27. x : 0,
  28. y : 0,
  29. width:0,
  30. onMove : false,
  31. init : function() {
  32. var s = this;
  33. captcha.captchaSlider.width = parseInt(captcha.conf.width);
  34. s.e = $("#captcha_slider")[0];
  35. s.e.addEventListener('mousedown', function(){
  36. s.onMouseDown(event, s);
  37. }, false);
  38. s.e.addEventListener('touchstart', function(){
  39. s.onMouseDown(event.touches[0], s);
  40. }, false);
  41. s.e.addEventListener('touchmove', function(){
  42. // console.log(event.touches[0].clientX)
  43. s.onMouseMove(event.touches[0], s);
  44. }, false);
  45. s.e.addEventListener('touchend', function(){
  46. s.onMouseUp(event.touches[0], s);
  47. }, false);
  48. },
  49. onMouseUp : function(e,t) {
  50. if(t.onMove){
  51. t.onMove = false;
  52. if(t.e.offsetLeft != 0){
  53. captcha.onVerify(100*t.e.offsetLeft / captcha.captchaSlider.width);
  54. t.e.style.left=0;
  55. $('#captcha_fragment')[0].style.left = t.e.style.left;
  56. }
  57. }
  58. },
  59. onMouseDown : function(e,t) {
  60. if(captcha.loaded){
  61. $("#captcha_panel")[0].style.display='block';
  62. $("#captcha_bg")[0].style.display='block';
  63. $("#captcha_fragment")[0].style.display='block';
  64. }
  65. t.onMove = true;
  66. t.x = e.clientX;
  67. t.y = e.clientY;
  68. },
  69. onMouseMove : function(e,t) {
  70. // console.log(t.width);
  71. if(t.onMove){
  72. if(e.clientX - t.x <=0){
  73. t.e.style.left = 0;
  74. }else if(e.clientX - t.x > t.width - t.e.clientWidth){
  75. t.e.style.left = (t.width - t.e.clientWidth) + "px";
  76. }else{
  77. t.e.style.left = (e.clientX - t.x) + "px";
  78. }
  79. $('#captcha_fragment')[0].style.left = t.e.style.left;
  80. }
  81. }
  82. },
  83. init : function(success, failure) {
  84. var elementDiv = $(this.conf.element);
  85. var type = this.conf.type;
  86. var captchaTemplateHtml = null;
  87. var captchaTemplateHtmlUpdateTime = null;
  88. if (window.localStorage) {
  89. captchaTemplateHtmlUpdateTime = window.localStorage.getItem(type + "captcha.html.time");
  90. if (Date.parse(new Date()) - captchaTemplateHtmlUpdateTime < 1)
  91. captchaTemplateHtml = window.localStorage.getItem(type + "captcha.html" + that.getLanguage());
  92. }
  93. if (captchaTemplateHtml == null) {
  94. var templateName="slide";
  95. if(that.getLanguage()=="en_US"){
  96. templateName+="_"+that.getLanguage();
  97. }
  98. templateName += '.html';
  99. var htmlTemplate= $.ajax({
  100. beforeSend: function(request) {
  101. request.setRequestHeader("Access-Control-Allow-Origin", "*");
  102. },
  103. url : captcha.conf.path + "captcha/" + templateName,
  104. async : false,
  105. cache : true
  106. });
  107. if (htmlTemplate.status = !200) {
  108. instance.log("captcha template loading error");
  109. failure("template html(captcha.html) can't be loaded");
  110. return;
  111. }
  112. if (window.localStorage) {
  113. window.localStorage.setItem(type + "captcha.html.time", Date.parse(new Date()));
  114. window.localStorage.setItem(type + "captcha.html" + that.getLanguage(), htmlTemplate.responseText);
  115. captchaTemplateHtml = htmlTemplate.responseText
  116. }
  117. }
  118. elementDiv.html(captchaTemplateHtml);
  119. var bg =document.getElementById('captcha_bg');
  120. bg.style.backgroundImage = "url('" +captcha.conf.path + "captcha/blank.png')";
  121. bg.style.backgroundSize = captcha.conf.bgSize + " 100%";
  122. bg.style.width = captcha.conf.width;
  123. //bg.style.height = captcha.conf.height;
  124. bg.style.height = "100%";
  125. var frag = document.getElementById('captcha_fragment');
  126. frag.style.backgroundImage = "url('" +captcha.conf.path + "captcha/blank.png')";
  127. frag.style.backgroundSize = captcha.conf.bgSize + " 100%";
  128. //frag.style.height = captcha.conf.height;
  129. frag.style.width = captcha.conf.fragWidth;
  130. frag.style.backgroundPosition = "-" + captcha.conf.width +" 0px";
  131. document.getElementById('captcha_main').style.width = captcha.conf.width;
  132. $("#captcha_refresh")[0].addEventListener('click', this.onRefresh, false);
  133. var slider = captcha.captchaSlider;
  134. window.addEventListener('mousemove', function(){slider.onMouseMove(event,slider)}, false);
  135. window.addEventListener('mouseup', function(){slider.onMouseUp(event,slider)}, false);
  136. this.captchaSlider.init();
  137. this.onRefresh();
  138. success(this);
  139. },
  140. refresh:function(){
  141. captcha.onRefresh();
  142. },
  143. onRefresh: function() {
  144. $.ajax({
  145. beforeSend: function(request) {
  146. request.setRequestHeader("Access-Control-Allow-Origin", "*");
  147. },
  148. url : captcha.conf.path + "captchas/get?type="+ captcha.conf.type+"&t="
  149. + Math.random() +"&width=" + captcha.conf.widthInt+"&height=" + captcha.conf.heightInt,
  150. success:function(resp){
  151. $("#captcha_bg").attr('src',"/captcha/blank.png");
  152. document.getElementById('captcha_bg').style.backgroundImage = "url('" +resp.data.backGround + "')";
  153. document.getElementById('captcha_fragment').style.backgroundImage = "url('" +resp.data.backGround + "')";
  154. captcha.data=resp.data;
  155. captcha.loaded = true;
  156. captcha.verified = false;
  157. that.$emit('getCaptchaToken', resp.data.token);
  158. $('.verification-result-slip').show();
  159. $('.slip-failed').hide();
  160. $('.slip-success').hide();
  161. $('.captcha_tips').show();
  162. },
  163. error:function(resp){
  164. captcha.log(resp.status);
  165. }
  166. });
  167. },
  168. onVerify : function(value){
  169. if(captcha.verified){
  170. return;
  171. }
  172. $("#captcha_panel")[0].style.display='none';
  173. $.ajax({
  174. beforeSend: function(request) {
  175. request.setRequestHeader("Access-Control-Allow-Origin", "*");
  176. },
  177. url : captcha.conf.path +"captchas/check?token="+captcha.data.token+"&data="+value,
  178. async : false,
  179. success:function(resp){
  180. that.$emit('getValidate', resp.validate)
  181. captcha.verified = resp.result;
  182. if(captcha.verified){
  183. $('.verification-result-slip').show();
  184. $('.slip-failed').hide();
  185. $('.captcha_tips').hide();
  186. $('.slip-success').show();
  187. $('#captcha_slider').hide();
  188. }else{
  189. $('.verification-result-slip').show();
  190. $('.slip-success').hide();
  191. $('.captcha_tips').hide();
  192. $('.slip-failed').show();
  193. // TODO 定时调用刷新
  194. }
  195. captcha.conf.onVerify(resp, captcha);
  196. },
  197. error:function(resp){
  198. captcha.log(resp.message);
  199. }
  200. });
  201. },
  202. debug : function(message) {
  203. // logLevel error[1],warning[2],log[3],debug[4],all[5]
  204. if (this.conf.logLevel >= 4) {
  205. console.log("captcha debug:" + message);
  206. }
  207. },
  208. log : function(message) {
  209. // logLevel error[1],warning[2],log[3],debug[4],all[5]
  210. if (this.conf.logLevel >= 3) {
  211. console.log("captcha log:" + message);
  212. }
  213. },
  214. warning : function(message) {
  215. // logLevel error[1],warning[2],log[3],debug[4],all[5]
  216. if (this.conf.logLevel >= 2) {
  217. console.log("captcha warning:" + message);
  218. }
  219. },
  220. error : function(message) {
  221. if (this.conf.logLevel >= 1) {
  222. console.log("captcha error:" + message);
  223. }
  224. }
  225. };
  226. captcha.init(success, failure);
  227. }
  228. },
  229. captchaInit(){
  230. let that = this
  231. that.initCaptcha(
  232. {
  233. element : '#captcha_div',// requred by type [3/4/5]
  234. logLevel : 5, // logLevel error[1],warning[2],log[3],debug[4],all[5]
  235. type : '3', // TEXT("字符验证码", 1), ARITHMETIC("数字计算验证码", 2), DRAG("滑动验证码", 3), CHOOSE("选择结果验证码", 4), POSITION("位置选择验证码", 5);
  236. width : "310px",
  237. onVerify : function(message, instance) {
  238. // console.log("check captcha:"+message.result);
  239. if (message.result) {
  240. $('.slip-success')[0].style.display = "inline-block";
  241. that.$emit('getResult', true)
  242. } else {
  243. $('.slip-failed')[0].style.display = "inline-block";
  244. instance.refresh();
  245. }
  246. }
  247. }, function(instance) {
  248. if (instance.conf.type >= 3) {
  249. // $('#tr_validation_code')[0].style.display = '';
  250. } else {
  251. // $('#tr_validation_code_input')[0].style.display = '';
  252. }
  253. instance.log("captcha instance initialization success, waiting for image loading");
  254. var capthcaInstance = instance;
  255. }, function(err) {alert(err);});
  256. },
  257. getCookie:function(name){
  258. var arr, reg = new RegExp("(^| )" + name + "=([^;]*)(;|$)");
  259. if (arr = document.cookie.match(reg))
  260. return unescape(arr[2]);
  261. else
  262. return null;
  263. },
  264. getLanguage:function(){
  265. if(this.getCookie("Language")){
  266. return this.getCookie("Language");
  267. }else{
  268. var lang =(navigator.language || navigator.browserLanguage).toLowerCase();
  269. if(lang.indexOf('en')>=0 ){
  270. return "en_US";
  271. }
  272. return "";
  273. }
  274. }
  275. }
  276. }
  277. </script>
  278. <style>
  279. </style>