safeUrl.js 1.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354
  1. /**
  2. * 安全打开外链:仅允许 http/https,并可按域名白名单限制
  3. */
  4. const DEFAULT_HOST_WHITELIST = [
  5. 'cdwjyyh.com',
  6. 'jnmyunl.com',
  7. 'obs.jnmyunl.com',
  8. 'cos.his.cdwjyyh.com'
  9. ]
  10. function isWhitelistedHost(hostname, whitelist) {
  11. if (!hostname) return false
  12. const host = hostname.toLowerCase()
  13. return whitelist.some(domain => host === domain || host.endsWith('.' + domain))
  14. }
  15. /**
  16. * @param {string} url
  17. * @param {object} [options]
  18. * @param {string[]} [options.hostWhitelist]
  19. * @returns {boolean}
  20. */
  21. export function isSafeHttpUrl(url, options = {}) {
  22. if (!url || typeof url !== 'string') return false
  23. const trimmed = url.trim()
  24. try {
  25. const u = new URL(trimmed)
  26. if (u.protocol !== 'http:' && u.protocol !== 'https:') return false
  27. if (u.username || u.password) return false
  28. const whitelist = options.hostWhitelist || DEFAULT_HOST_WHITELIST
  29. if (whitelist.length > 0 && !isWhitelistedHost(u.hostname, whitelist)) {
  30. return false
  31. }
  32. return true
  33. } catch (e) {
  34. return false
  35. }
  36. }
  37. /**
  38. * 安全 window.open
  39. */
  40. export function safeOpen(url, target = '_blank') {
  41. if (!isSafeHttpUrl(url)) {
  42. console.warn('拒绝打开不安全链接:', url)
  43. return null
  44. }
  45. return window.open(url, target, 'noopener,noreferrer')
  46. }
  47. export default {
  48. isSafeHttpUrl,
  49. safeOpen
  50. }