推拿小程序前端代码仓库
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

145 lines
3.8 KiB

  1. // H5 路由和环境修复
  2. // #ifdef H5
  3. // 存储原始方法
  4. let originalGetCurrentPages;
  5. let originalHistoryReplaceState;
  6. let isFixed = false;
  7. // 修复H5环境路由问题的主函数
  8. export function fixH5Router() {
  9. if (isFixed) return;
  10. try {
  11. // 1. 修复 getCurrentPages 方法
  12. if (typeof getCurrentPages === 'function') {
  13. originalGetCurrentPages = getCurrentPages;
  14. window.getCurrentPages = function() {
  15. try {
  16. const pages = originalGetCurrentPages();
  17. if (pages && Array.isArray(pages)) {
  18. // 确保每个页面对象有必要的属性
  19. pages.forEach((page, index) => {
  20. if (!page.route) {
  21. page.route = page.$page?.fullPath || `page_${index}`;
  22. }
  23. if (!page.options) {
  24. page.options = {};
  25. }
  26. // 确保页面有 meta 属性
  27. if (page.$page && !page.$page.meta) {
  28. page.$page.meta = {};
  29. }
  30. });
  31. }
  32. return pages || [];
  33. } catch(e) {
  34. console.warn('getCurrentPages 执行失败:', e);
  35. return [{
  36. route: '/',
  37. options: {},
  38. $page: { meta: {} }
  39. }];
  40. }
  41. };
  42. }
  43. // 2. 修复 History API
  44. if (window.history && window.history.replaceState) {
  45. originalHistoryReplaceState = window.history.replaceState;
  46. window.history.replaceState = function(state, title, url) {
  47. try {
  48. // 修复 URL 格式问题
  49. if (url && typeof url === 'string') {
  50. // 处理错误的 URL 格式
  51. if (url.includes('https:/#/')) {
  52. url = url.replace(/https:\/+#\//, window.location.origin + '/#/');
  53. }
  54. // 确保相对路径的正确性
  55. if (url.startsWith('#/')) {
  56. url = window.location.origin + window.location.pathname + url;
  57. }
  58. // 处理双斜杠问题
  59. url = url.replace(/([^:]\/)\/+/g, '$1');
  60. }
  61. return originalHistoryReplaceState.call(this, state, title, url);
  62. } catch(e) {
  63. console.warn('History.replaceState 修复执行失败:', e);
  64. // 忽略错误,不执行原方法
  65. return null;
  66. }
  67. };
  68. }
  69. // 3. 添加全局错误处理
  70. const originalOnError = window.onerror;
  71. window.onerror = function(message, source, lineno, colno, error) {
  72. // 过滤已知的H5兼容性错误
  73. if (typeof message === 'string') {
  74. if (message.includes("Cannot read property 'meta'") ||
  75. message.includes('replaceState') ||
  76. message.includes('showTabBar') ||
  77. message.includes('History')) {
  78. console.warn('H5兼容性错误已忽略:', message);
  79. return true; // 阻止默认错误处理
  80. }
  81. }
  82. // 其他错误交给原处理器
  83. if (originalOnError) {
  84. return originalOnError(message, source, lineno, colno, error);
  85. }
  86. return false;
  87. };
  88. // 4. 修复 URL 哈希处理
  89. if (window.location.hash === '' || window.location.hash === '#') {
  90. window.location.hash = '#/';
  91. }
  92. // 5. 监听 hashchange 事件,确保路由正常
  93. window.addEventListener('hashchange', function(e) {
  94. try {
  95. const hash = window.location.hash;
  96. if (!hash || hash === '#') {
  97. window.location.hash = '#/';
  98. }
  99. } catch(e) {
  100. console.warn('hashchange 处理失败:', e);
  101. }
  102. });
  103. isFixed = true;
  104. console.log('H5 路由修复完成');
  105. } catch(e) {
  106. console.warn('H5 路由修复失败:', e);
  107. }
  108. }
  109. // 恢复原始方法(用于调试)
  110. export function restoreH5Router() {
  111. if (!isFixed) return;
  112. try {
  113. if (originalGetCurrentPages) {
  114. window.getCurrentPages = originalGetCurrentPages;
  115. }
  116. if (originalHistoryReplaceState) {
  117. window.history.replaceState = originalHistoryReplaceState;
  118. }
  119. isFixed = false;
  120. console.log('H5 路由修复已恢复');
  121. } catch(e) {
  122. console.warn('H5 路由恢复失败:', e);
  123. }
  124. }
  125. // 页面加载完成后自动执行修复
  126. if (document.readyState === 'loading') {
  127. document.addEventListener('DOMContentLoaded', fixH5Router);
  128. } else {
  129. fixH5Router();
  130. }
  131. // #endif