leancloud.js 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192
  1. /* global CONFIG */
  2. // eslint-disable-next-line no-console
  3. (function(window, document) {
  4. // 查询存储的记录
  5. function getRecord(Counter, target) {
  6. return new Promise(function(resolve, reject) {
  7. Counter('get', '/classes/Counter?where=' + encodeURIComponent(JSON.stringify({ target })))
  8. .then(resp => resp.json())
  9. .then(({ results, code, error }) => {
  10. if (code === 401) {
  11. throw error;
  12. }
  13. if (results && results.length > 0) {
  14. var record = results[0];
  15. resolve(record);
  16. } else {
  17. Counter('post', '/classes/Counter', { target, time: 0 })
  18. .then(resp => resp.json())
  19. .then((record, error) => {
  20. if (error) {
  21. throw error;
  22. }
  23. resolve(record);
  24. }).catch(error => {
  25. console.error('Failed to create: ', error);
  26. reject(error);
  27. });
  28. }
  29. }).catch((error) => {
  30. console.error('LeanCloud Counter Error: ', error);
  31. reject(error);
  32. });
  33. });
  34. }
  35. // 发起自增请求
  36. function increment(Counter, incrArr) {
  37. return new Promise(function(resolve, reject) {
  38. Counter('post', '/batch', {
  39. 'requests': incrArr
  40. }).then((res) => {
  41. res = res.json();
  42. if (res.error) {
  43. throw res.error;
  44. }
  45. resolve(res);
  46. }).catch((error) => {
  47. console.error('Failed to save visitor count: ', error);
  48. reject(error);
  49. });
  50. });
  51. }
  52. // 构建自增请求体
  53. function buildIncrement(objectId) {
  54. return {
  55. 'method': 'PUT',
  56. 'path' : `/1.1/classes/Counter/${objectId}`,
  57. 'body' : {
  58. 'time': {
  59. '__op' : 'Increment',
  60. 'amount': 1
  61. }
  62. }
  63. };
  64. }
  65. // 校验是否为有效的 Host
  66. function validHost() {
  67. if (CONFIG.web_analytics.leancloud.ignore_local) {
  68. var hostname = window.location.hostname;
  69. if (hostname === 'localhost' || hostname === '127.0.0.1') {
  70. return false;
  71. }
  72. }
  73. return true;
  74. }
  75. // 校验是否为有效的 UV
  76. function validUV() {
  77. var key = 'LeanCloud_UV_Flag';
  78. var flag = localStorage.getItem(key);
  79. if (flag) {
  80. // 距离标记小于 24 小时则不计为 UV
  81. if (new Date().getTime() - parseInt(flag, 10) <= 86400000) {
  82. return false;
  83. }
  84. }
  85. localStorage.setItem(key, new Date().getTime().toString());
  86. return true;
  87. }
  88. function addCount(Counter) {
  89. var enableIncr = CONFIG.web_analytics.enable && !Fluid.ctx.dnt && validHost();
  90. var getterArr = [];
  91. var incrArr = [];
  92. // 请求 PV 并自增
  93. var pvCtn = document.querySelector('#leancloud-site-pv-container');
  94. if (pvCtn) {
  95. var pvGetter = getRecord(Counter, 'site-pv').then((record) => {
  96. enableIncr && incrArr.push(buildIncrement(record.objectId));
  97. var ele = document.querySelector('#leancloud-site-pv');
  98. if (ele) {
  99. ele.innerText = (record.time || 0) + (enableIncr ? 1 : 0);
  100. pvCtn.style.display = 'inline';
  101. }
  102. });
  103. getterArr.push(pvGetter);
  104. }
  105. // 请求 UV 并自增
  106. var uvCtn = document.querySelector('#leancloud-site-uv-container');
  107. if (uvCtn) {
  108. var uvGetter = getRecord(Counter, 'site-uv').then((record) => {
  109. var incrUV = validUV() && enableIncr;
  110. incrUV && incrArr.push(buildIncrement(record.objectId));
  111. var ele = document.querySelector('#leancloud-site-uv');
  112. if (ele) {
  113. ele.innerText = (record.time || 0) + (incrUV ? 1 : 0);
  114. uvCtn.style.display = 'inline';
  115. }
  116. });
  117. getterArr.push(uvGetter);
  118. }
  119. // 如果有页面浏览数节点,则请求浏览数并自增
  120. var viewCtn = document.querySelector('#leancloud-page-views-container');
  121. if (viewCtn) {
  122. var path = eval(CONFIG.web_analytics.leancloud.path || 'window.location.pathname');
  123. var target = decodeURI(path.replace(/\/*(index.html)?$/, '/'));
  124. var viewGetter = getRecord(Counter, target).then((record) => {
  125. enableIncr && incrArr.push(buildIncrement(record.objectId));
  126. var ele = document.querySelector('#leancloud-page-views');
  127. if (ele) {
  128. ele.innerText = (record.time || 0) + (enableIncr ? 1 : 0);
  129. viewCtn.style.display = 'inline';
  130. }
  131. });
  132. getterArr.push(viewGetter);
  133. }
  134. // 如果启动计数自增,批量发起自增请求
  135. if (enableIncr) {
  136. Promise.all(getterArr).then(() => {
  137. incrArr.length > 0 && increment(Counter, incrArr);
  138. });
  139. }
  140. }
  141. var appId = CONFIG.web_analytics.leancloud.app_id;
  142. var appKey = CONFIG.web_analytics.leancloud.app_key;
  143. var serverUrl = CONFIG.web_analytics.leancloud.server_url;
  144. if (!appId) {
  145. throw new Error('LeanCloud appId is empty');
  146. }
  147. if (!appKey) {
  148. throw new Error('LeanCloud appKey is empty');
  149. }
  150. function fetchData(api_server) {
  151. var Counter = (method, url, data) => {
  152. return fetch(`${api_server}/1.1${url}`, {
  153. method,
  154. headers: {
  155. 'X-LC-Id' : appId,
  156. 'X-LC-Key' : appKey,
  157. 'Content-Type': 'application/json'
  158. },
  159. body: JSON.stringify(data)
  160. });
  161. };
  162. addCount(Counter);
  163. }
  164. var apiServer = serverUrl || `https://${appId.slice(0, 8).toLowerCase()}.api.lncldglobal.com`;
  165. if (apiServer) {
  166. fetchData(apiServer);
  167. } else {
  168. fetch('https://app-router.leancloud.cn/2/route?appId=' + appId)
  169. .then(resp => resp.json())
  170. .then((data) => {
  171. if (data.api_server) {
  172. fetchData('https://' + data.api_server);
  173. }
  174. });
  175. }
  176. })(window, document);