webLink.ts 1.7 KB

1234567891011121314151617181920212223242526272829303132333435
  1. // lib/webLink.ts:判断「给个链接能不能丢进右侧面板 iframe 打开」,以及生成标签标题。
  2. //
  3. // 当前不区分站内站外:只要是 http(s) 地址就放行(后端返回的内网系统地址多为同域不同端口,
  4. // 按同源判定会被排除,先用「全放开」)—— 具体见需求:先不做限制,后续再收紧。
  5. // 非 http(s) 协议(mailto/tel/javascript/data/blob)和页内锚点(#xxx)无法进 iframe,仍返回 null。
  6. //
  7. // 注意:外链能否真的被嵌由对方站点决定(X-Frame-Options: DENY/SAMEORIGIN 或 CSP frame-ancestors 会被
  8. // 浏览器直接拒绝,面板里只会一片空白,且跨域读不到内容、前端无法可靠识别),所以面板里始终保留
  9. // 「新窗口打开」兜底。以后要收紧成白名单/同源,只改这里的判定即可。
  10. /** 取出可放进面板的绝对地址;http(s) 以外的协议、页内锚点、空链接返回 null */
  11. export const panelOpenableUrl = (href?: string | null): string | null => {
  12. const raw = (href || '').trim();
  13. if (!raw || raw.startsWith('#')) return null;
  14. try {
  15. const url = new URL(raw, window.location.href);
  16. if (url.protocol !== 'http:' && url.protocol !== 'https:') return null;
  17. return url.href;
  18. } catch {
  19. // 非法 URL
  20. return null;
  21. }
  22. };
  23. /** 面板标签标题:优先用链接文字,没有就用路径(去掉域名,整条 URL 会把标签栏挤爆) */
  24. export const webTabTitle = (href: string, text?: string): string => {
  25. const label = (text || '').replace(/\s+/g, ' ').trim();
  26. if (label) return label;
  27. try {
  28. const url = new URL(href, window.location.href);
  29. return url.pathname + url.search || url.host;
  30. } catch {
  31. return href;
  32. }
  33. };