开发Tips|用JS判断并采集webpack路由

最近开发网站监测平台的时候,发现被监测的网站可能存在webpack的打包情况,如http://xxxx/#/login,类似这种由路由处理时直接由request无法判定需要借助无头浏览器进行URL采集,所以这里提供一个JS方案来实现webpack的判定。

01
JavaScript代码-判断是否为webpack打包

function isWebpackUsed() {
// 检查全局变量 webpack_require
if (typeof webpack_require !== ‘undefined’) {
console.log(‘Webpack detected: webpack_require is defined.’);
return true;
}

// 检查 script 标签中是否包含 webpack 相关的特征
const scripts = document.getElementsByTagName(‘script’);
for (let script of scripts) {
if (script.src && script.src.includes(‘webpack’)) {
console.log(‘Webpack detected: script src contains “webpack”.’);
return true;
}
}

// 检查页面中是否包含 webpack 打包的 chunk 文件
const resources = performance.getEntriesByType(‘resource’);
for (let resource of resources) {
if (resource.name.includes(‘webpack’) || resource.name.includes(‘chunk’)) {
console.log(‘Webpack detected: resource name contains “webpack” or “chunk”.’);
return true;
}
}

console.log(‘No Webpack detected.’);
return false;
}

// 调用函数检测
console.log(isWebpackUsed());

02
JavaScript代码-获取路由

此js代码来自于志远大佬的开源项目。

function findVueRoot(root) {
const queue = [root];
while (queue.length > 0) {
const currentNode = queue.shift();

if (currentNode.__vue__ || currentNode.__vue_app__ || currentNode._vnode) {
  console.log("vue detected on root element:", currentNode);
  return currentNode
}

for (let i = 0; i < currentNode.childNodes.length; i++) {
  queue.push(currentNode.childNodes[i]);
}

}

return null;
}

function findVueRouter(vueRoot) {
let router;

try {
if (vueRoot.vue_app) {
router = vueRoot.vue_app.config.globalProperties.$router.options.routes
console.log(“find router in Vue object”, vueRoot.vue_app)
} else if (vueRoot.vue) {
router = vueRoot.vue.$root.$options.router.options.routes
console.log(“find router in Vue object”, vueRoot.vue)
}
} catch (e) {}

try {
if (vueRoot.vue && !router) {
router = vueRoot.vue._router.options.routes
console.log(“find router in Vue object”, vueRoot.vue)
}
} catch (e) {}

return router
}

function walkRouter(rootNode, callback) {
const stack = [{node: rootNode, path: ”}];

while (stack.length) {
const { node, path} = stack.pop();

if (node && typeof node === 'object') {
  if (Array.isArray(node)) {
    for (const key in node) {
      stack.push({node: node[key], path: mergePath(path, node[key].path)})
    }
  } else if (node.hasOwnProperty("children")) {
    stack.push({node: node.children, path: path});
  }
}

callback(path, node);

}
}

function mergePath(parent, path) {
if (path.indexOf(parent) === 0) {
return path
}

return (parent ? parent + ‘/’ : ”) + path
}

function main() {
const vueRoot = findVueRoot(document.body);
if (!vueRoot) {
console.error(“This website is not developed by Vue”)
return
}

let vueVersion;
if (vueRoot.vue) {
vueVersion = vueRoot.vue.$options._base.version;
} else {
vueVersion = vueRoot.vue_app.version;
}

console.log(“Vue version is “, vueVersion)
const routers = [];

const vueRouter = findVueRouter(vueRoot)
if (!vueRouter) {
console.error(“No Vue-Router detected”)
return
}

console.log(vueRouter)
walkRouter(vueRouter, function (path, node) {
if (node.path) {
routers.push({name: node.name, path})
}
})

return routers
}

console.table(main())
03
效果

01
存在Webpack打包情况

获取路由也是可以直接获取的。

02
不存在Webpack打包情况

04
开发思路

通过拉起一个selenium对页面插入webpack监测代码获取执行结果,而后进行判断是否进行路由拼接,若可以获取路由结果,在页面加载过程中可能采集到更多的URL。

声明:文中观点不代表本站立场。本文传送门:https://eyangzhen.com/424563.html

联系我们
联系我们
分享本页
返回顶部