// var base64 = base64 || (function() { // var base64Map = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/".split(''); // var base64DeMap = ! function() { // var result = {}; // $.each(base64Map, function(i, e) { // result[e] = i; // }); // return result; // }(); // var target = {}; // target.encode = function(data) { // var buf = []; // var map = base64Map; // var n = data.length; //总字节数 // var val; //中间值 // var i = 0; // /* // * 3字节 ==> val ==> 4字符 // */ // while (i < n) { // val = (data[i] << 16) | // (data[i + 1] << 8) | // (data[i + 2]); // buf.push(map[val >> 18], // map[val >> 12 & 63], // map[val >> 6 & 63], // map[val & 63]); // i += 3; // } // if (n % 3 == 1) //凑两个"=" // buf.pop(), buf.pop(), buf.push('=', '='); // else //凑一个"=" // buf.pop(), buf.push('='); // return buf.join(''); // }; // target.decode = function(str) { // var buf = []; // var arr = str.split(''); // var map = base64DeMap; // var n = arr.length; //总字符数 // var val; //中间值 // var i = 0; // /* // * 长度异常 // */ // if (n % 4) // return null; // /* // * 4字符 ==> val ==> 3字节 // */ // while (i < n) { // val = (map[arr[i]] << 18) | // (map[arr[i + 1]] << 12) | // (map[arr[i + 2]] << 6) | // (map[arr[i + 3]]); // buf.push(val >> 16, // val >> 8 & 0xFF, // val & 0xFF); // i += 4; // } // /* // * 凑字字符"="个数 // */ // while (arr[--n] == '=') // buf.pop(); // return buf; // }; // target.encodeArrayBuffer = function(arrayBuffer) { // /// 将ArrayBuffer转换为Base64字符串 // var dv = new DataView(arrayBuffer); // var length = dv.byteLength; // var data = []; // for (var i = 0; i < length; i++) { // data.push(dv.getUint8(i)); // } // return base64.encode(data); // }; // target.toObjectUrl = function(base64str, type) { // /// 获得指定base64字符串的对象链接格式 // return "data:" + type + ";base64," + base64str; // }; // return target; // })(); var bootStrap = (function() { var def = $.Deferred(); // alert(typeof __TicketJavaScriptObject__); var isAndroid = typeof(__TicketJavaScriptObject__) !== 'undefined'; var isIos = typeof(window.__ksticket) != 'undefined' || typeof(window.__gChrome) != 'undefined'; var isOldBrowser = typeof(window.__ksticket) != 'undefined' || typeof(window.liebaoExtentions) !== 'undefined'; var deviceObject = window.__TicketJavaScriptObject__ || window.__ksticket; var isExtension = document.body.dataset["mobileSupportInitialized"] || false; Object.defineProperties(def, { 'isAndroid': { get: function() { return isAndroid; } }, 'isIos': { get: function() { return isIos; } }, 'isIosOld': { get: function() { return !isOldBrowser; } }, 'device_info': { get: function() { if (deviceObject) return deviceObject.get_device_info(); return null; } } }); def.open_url = function(url) { if (deviceObject) { deviceObject.open_url(url); } else { window.open(url); } } def.refresh_start = function() { var args = [].slice.call(arguments); if (deviceObject) { // deviceObject.refresh_start.apply(this, arguments); deviceObject.refresh_start(); } // $(document).dispatchEvent("refreshStart", args); }; def.refresh_end = function() { var args = [].slice.call(arguments); if (deviceObject) { // deviceObject.refresh_end.apply(this, arguments); deviceObject.refresh_end(); } // $(document).dispatchEvent("refreshEnd", args); }; def.refresh_success = function() { var args = [].slice.call(arguments); if (deviceObject) { // deviceObject.refresh_success.apply(this, arguments); deviceObject.refresh_success(); try { deviceObject.toast('刷票成功,请尽快订票'); } catch (e) { } } else if (window.liebaoExtentions && window.liebaoExtentions.vibrate) { window.liebaoExtentions.vibrate(5000); } else if (window.__gChrome && window.__gChrome.hasTicket) { window.__gChrome.hasTicket("刷票成功,请尽快订票", ""); } // $(document).dispatchEvent("refreshSuccess", args); }; var queue = {}; var callid = 0; var ajaxCommon = (function() { var baseUri = "https://kyfw.12306.cn/otn/"; return { getUrl: function(url) { if (url[4] === ":" || url[5] === ":") return url; return baseUri + url; }, getHeaders: function(url, headers) { headers = headers || {}; headers['Origin'] = /(https?:\/\/[^\/]+\/)/i.exec(url)[1]; if (isIos) { var nheaders = {}; $.each(headers, function(k, v) { nheaders["Fish-" + k] = v; }); headers = nheaders; } return headers; } }; })(); var ajaxAndLb = (function() { window.fishXhrLoadCallback = function(obj) { if (typeof(obj) === "string") obj = JSON.parse(obj); var ad = queue[obj.id]; if (!ad) return; //process with json if (ad.rawResultType === "json") { try { obj.result = JSON.parse(obj.result); } catch (e) { obj.success = false; } } else if (ad.rawResultType === "image") { obj.result = base64.toObjectUrl(obj.result, "png"); } delete queue[obj.id]; if (obj.success) { ad.resolve(obj.result, { headers: obj.headers, statusCode: obj.statusCode, statusDescription: obj.statusDescription, id: obj.id }); } else { ad.reject(obj.result, { headers: obj.headers, statusCode: obj.statusCode, statusDescription: obj.statusDescription, id: obj.id }); } }; var ajax = function(method, url, returnType, postdata, refer, headers) { var ad = new $.Deferred(); postdata = postdata || ""; if (typeof(postdata) !== "string") postdata = $.param(postdata); if (method == 'GET' && (returnType || "json") != "image") { url = url + "?" + postdata; } headers = headers || {}; if (refer) { headers = $.extend({}, headers, { Referer: refer }); } ad.rawResultType = returnType || "json"; ad.context = { id: ++callid, url: url, method: method, postdata: postdata, refer: refer, headers: headers || {}, callback: "fishXhrLoadCallback", requestCharset: "UTF-8", returnType: ad.rawResultType === "image" ? "image" : "text" }; queue[ad.context.id] = ad; deviceObject.sendRequest(JSON.stringify(ad.context)); return ad.promise(); }; return { ajax: ajax, get: function() { var arr = [].slice.call(arguments); arr.unshift("GET"); return ajax.apply(this, arr); }, post: function() { var arr = [].slice.call(arguments); arr.unshift("POST"); return ajax.apply(this, arr); }, getImage: function(url, refer) { return ajax("GET", url, "image", null, refer); } } })(); var ajaxIos = (function() { //ios var ajax = function(method, url, returnType, postdata, refer, headers) { var ad = new $.Deferred(); headers = headers || {}; if (refer) { headers = $.extend({}, headers, { Referer: refer }); } var nheaders = {}; $.each(headers, function(k, v) { nheaders["Fish-" + k] = v; }); headers = nheaders; $.ajax({ url: url, data: postdata, timeout: 120000, type: method, dataType: returnType, refer: refer, headers: headers }).done(function(result, status, xhr) { ad.resolve(result, { headers: xhr.getAllResponseHeaders(), statusCode: xhr.statusCode, statusDescription: xhr.statusText, id: 0 }); }).fail(function(xhr) { ad.reject(result, { headers: xhr.getAllResponseHeaders(), statusCode: xhr.statusCode, statusDescription: xhr.statusText, id: 0 }); }); return ad; }; var ajaxLoadImage = function(method, url, postdata, refer, headers) { var ad = new $.Deferred(); var xhr = new window.XMLHttpRequest(); headers = headers || {}; xhr.open(method, url, true); $.each(headers, function(k, v) { xhr.setRequestHeader("Fish-" + k, v); }); xhr.onreadystatechange = function() { if (xhr.readyState === 4) { if (xhr.status !== 200) { ad.reject("加载验证码失败,请点击验证码刷新", { headers: xhr.getAllResponseHeaders(), statusCode: xhr.statusCode, statusDescription: xhr.statusText, id: 0 }); } else { ad.resolve(base64.toObjectUrl(base64.encodeArrayBuffer(xhr.response), "image/jpeg"), { headers: xhr.getAllResponseHeaders(), statusCode: xhr.statusCode, statusDescription: xhr.statusText, id: 0 }); } } }; var prefix = "Fish-"; xhr.responseType = "arraybuffer"; xhr.setRequestHeader(prefix + "Referer", refer || ""); xhr.setRequestHeader(prefix + "User-Agent", "Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Trident/5.0)"); xhr.setRequestHeader(prefix + "Origin", /(https?:\/\/[^\/]+\/)/.exec(url)[1]); xhr.send(postdata); return ad; } return { ajax: ajax, get: function() { var arr = [].slice.call(arguments); arr.unshift("GET"); return ajax.apply(this, arr); }, post: function() { var arr = [].slice.call(arguments); arr.unshift("POST"); return ajax.apply(this, arr); }, getImage: function(url, refer) { return ajaxLoadImage("GET", url, null, refer); } } })(); var ajaxExtension = (function() { //ios var ajax = function(method, url, returnType, postdata, refer, headers) { var ad = new $.Deferred(); headers = headers || {}; if (refer) { headers = $.extend({}, headers, { Referer: refer }); } var xhrData = { url: url, data: postdata, timeout: 120000, type: method, dataType: returnType, refer: refer, headers: headers }; var e = new CustomEvent("ajaxproxy", { detail: { data: xhrData, index: ++callid }, cancelable: true }); if (!document.dispatchEvent(e)) { queue[e.detail.index] = { done: function(result) { ad.resolve(result, { headers: this.headers, statusCode: this.status, statusDescription: this.statusText, id: this.index }); }, fail: function() { ad.reject(this.text, { headers: this.headers, statusCode: this.status, statusDescription: this.statusText, id: this.index }); } }; } else { document.dispatchEvent(new CustomEvent("requestSupportError")); def.reject("平台错误"); } return ad; }; var ajaxLoadImage = function(method, url, postdata, refer, headers) { var ad = new $.Deferred(); headers = headers || {}; if (refer) { headers = $.extend({}, headers, { Referer: refer }); } var e = new CustomEvent("ajaxLoadVerifyCode", { detail: { method: method, url: url, refer: refer, index: ++callid, headers: headers, data: postdata }, cancelable: true }); if (!document.dispatchEvent(e)) { queue[e.detail.index] = { done: function() { ad.resolve(this.url, { headers: this.headers, statusCode: this.status, statusDescription: this.statusText, id: this.index }); }, fail: function() { ad.reject(this.text, { headers: this.headers, statusCode: this.status, statusDescription: this.statusText, id: this.index }); } }; } else { document.dispatchEvent(new CustomEvent("requestSupportError")); ad.reject("平台错误"); } return ad; } document.addEventListener("ajaxproxyfinished", function(e) { var data = e.detail; if (!queue[data.index]) return; var param = queue[data.index]; delete queue[data.index]; if (data.status === 404) { //404是个比较特殊的错误,这个错误一般是证书有问题 document.dispatchEvent(new CustomEvent("networkOrCertificationError")); } data.success ? param.done.call(data || window, data.model) : param.fail.call(data || window, data.model); }); return { ajax: ajax, get: function() { var arr = [].slice.call(arguments); arr.unshift("GET"); return ajax.apply(this, arr); }, post: function() { var arr = [].slice.call(arguments); arr.unshift("POST"); return ajax.apply(this, arr); }, getImage: function(url, refer) { return ajaxLoadImage("GET", url, null, refer); } } })(); var ajaxProxy = (function() { var ajax = function(method, url, returnType, postdata, refer, headers) { var ad = new $.Deferred(); var headers = headers || {}; returnType = returnType || 'json'; // headers = headers || {}; if (refer) { headers = $.extend({}, headers, { Referer: refer }); } var header = {}; for (var k in headers) { header["FISHPROXY-" + k] = headers[k]; }; header["FISHPROXY-RawUrl"] = url; url = "/12306/proxy.php"; $.ajax({ url: url, data: postdata, timeout: 120000, type: method, dataType: returnType, refer: refer, headers: header }).done(function(result, status, xhr) { ad.resolve(result, { headers: xhr.getAllResponseHeaders(), statusCode: xhr.statusCode, statusDescription: xhr.statusText, id: 0 }); }).fail(function(xhr) { ad.reject(xhr.responseText, { headers: xhr.getAllResponseHeaders(), statusCode: xhr.statusCode, statusDescription: xhr.statusText, id: 0 }); }); return ad; }; var ajaxLoadImage = function(method, url, postdata, refer, headers) { var ad = new $.Deferred(); var xhr = new window.XMLHttpRequest(); headers = headers || {}; headers["RawUrl"] = url; headers["Origin"] = /(https?:\/\/[^\/]+\/)/.exec(url)[1]; headers["User-Agent"] = "Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Trident/5.0)"; headers["Referer"] = refer || ""; url = "/12306/proxy.php"; xhr.open(method, url, true); $.each(headers, function(k, v) { xhr.setRequestHeader("FISHPROXY-" + k, v); }); xhr.onreadystatechange = function() { if (xhr.readyState === 4) { if (xhr.status !== 200) { ad.reject("加载验证码失败,请点击验证码刷新", { headers: xhr.getAllResponseHeaders(), statusCode: xhr.statusCode, statusDescription: xhr.statusText, id: 0 }); } else { ad.resolve(base64.toObjectUrl(base64.encodeArrayBuffer(xhr.response), "image/jpeg"), { headers: xhr.getAllResponseHeaders(), statusCode: xhr.statusCode, statusDescription: xhr.statusText, id: 0 }); } } }; xhr.responseType = "arraybuffer"; xhr.send(postdata || null); return ad; } return { ajax: ajax, get: function() { var arr = [].slice.call(arguments); arr.unshift("GET"); return ajax.apply(this, arr); }, post: function() { var arr = [].slice.call(arguments); arr.unshift("POST"); return ajax.apply(this, arr); }, getImage: function(url, refer) { return ajaxLoadImage("GET", url, null, refer); } } })(); def.getAjaxComponent = function() { return (isAndroid ? ajaxAndLb : (isIos ? ajaxIos : (isExtension ? ajaxExtension : ajaxProxy))); }; def.ajax = function() { var args = [].slice.call(arguments); if (args[1]) args[1] = ajaxCommon.getUrl(args[1]); if (args[4]) args[4] = ajaxCommon.getUrl(args[4]); if (args[5]) args[5] = ajaxCommon.getHeaders(args[5]); return def.getAjaxComponent().ajax.apply(this, args); }; def.get = function() { var args = [].slice.call(arguments); args.unshift("GET"); return def.ajax.apply(this, args); }; def.post = function() { var args = [].slice.call(arguments); args.unshift("POST"); return def.ajax.apply(this, args); }; def.getImage = function() { var args = [].slice.call(arguments); if (args[1]) args[1] = ajaxCommon.getUrl(args[1]); if (args[3]) args[3] = ajaxCommon.getUrl(args[3]); if (args[5]) args[4] = ajaxCommon.getHeaders(args[4]); return def.getAjaxComponent().getImage.apply(this, args); }; $(function() { if (isIos || isExtension || isAndroid) { def.resolve(); } else { var timer = setTimeout(function() { def.resolve(); }, 500); document.addEventListener("mobileSupportInitialized", function() { clearTimeout(timer); isExtension = true; def.resolve(); }); } }); return def; })(); bootStrap.done(function() { Client.init(); Public.init(); Login.init(); Query.init(); RunQuery.init(); OrderSubmit.init(); NoComplete.init(); MyRemind.init(); Remind.init(); OrderList.init(); var adUrl = 'http://dl.liebao.cn/android/fast/cheetah_2.11.0.apk', iosUrl = 'https://itunes.apple.com/cn/app/id641522896', downloadUrl = IsIOS ? iosUrl : adUrl, lowerUA = UA.toLowerCase(), IsLiebao = lowerUA.match(/LieBao/i) == 'liebao', IsConfirm = tryShowConfrim(); // IsConfirm = true; // alert(IsConfirm); if (lowerUA.match(/MicroMessenger/i) == "micromessenger") { $('body').prepend('').addClass('showBanner'); } else if (!(bootStrap.isIos || bootStrap.isAndroid) && ($('#myremind_page').length == 0 && $('#remind_page').length == 0)) { if (IsLiebao) { if (lowerUA.match(/LieBaoFast/i) == "liebaofast") { if(IsConfirm){ Public.confirm('请升级至最新版本', Public.updateAndroid, '立即升级'); setShowADConfrimTime(); } } else if (IsAndroid) { $('body').prepend('').addClass('showBanner'); if(IsConfirm){ Public.confirm('手机猎豹极速版全新体验,更轻、更快、更安全!', Public.updateAndroid, '立即升级'); setShowADConfrimTime(); } } else { //iOS低版本猎豹处理 } } else { // 非猎豹处理 $('body').prepend('').addClass('showBanner'); if(IsConfirm){ Public.confirm('下载手机猎豹浏览器,手机抢票更快、更方便。', IsIOS ? Public.updateIos : Public.updateAndroid, '立即下载'); setShowADConfrimTime(); } } } function tryShowConfrim() { var page = $('body').attr('id')||'', t = localStorage.getItem(page+'confirmTime'); // alert(t); if (!t) { // alert(1); return true; } if ((new Date(parseInt(t))).date.getTime() < (new Date).date.getTime()) { // alert(2) return true; } return false; } function setShowADConfrimTime(){ var page = $('body').attr('id')||''; localStorage.setItem(page+'confirmTime',(new Date()).getTime()); } });