You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Angular9+如何全局白名单放行whatsapp://等自定义协议

Angular 9+ 全局添加自定义URL协议白名单方案

Angular 9及以上版本没有提供和AngularJS完全一致的aHrefSanitizationWhitelist公开配置项,但可以通过两种方案实现全局添加自定义协议白名单的需求,无需对每个链接单独做安全校验处理。

方案一:重写DomSanitizer实现(代码量最少)

通过继承Angular内置的DomSanitizer实现类,扩展URL安全校验规则,全局覆盖默认逻辑:

import { NgModule } from '@angular/core';
import { BrowserModule, DomSanitizerImpl, ɵDomSanitizerImpl } from '@angular/platform-browser';
import { AppComponent } from './app.component';

// 自定义安全校验逻辑
class CustomDomSanitizer extends ɵDomSanitizerImpl {
  override sanitize(context: any, value: any): string | null {
    // 匹配URL校验场景
    if (context === 1 /* SecurityContext.URL */ && typeof value === 'string') {
      // 可自定义需要加入白名单的协议
      const allowedCustomProtocols = /^\s*(whatsapp|fb-messenger|sms|tel):/i;
      if (allowedCustomProtocols.test(value)) {
        return value;
      }
    }
    // 其他场景保留默认校验逻辑
    return super.sanitize(context, value);
  }
}

@NgModule({
  declarations: [AppComponent],
  imports: [BrowserModule],
  providers: [
    // 用自定义实现覆盖默认DomSanitizer
    { provide: DomSanitizerImpl, useClass: CustomDomSanitizer },
    { provide: ɵDomSanitizerImpl, useClass: CustomDomSanitizer }
  ],
  bootstrap: [AppComponent]
})
export class AppModule {}

注意:该方案用到了Angular内部API(前缀为ɵ的导出项),跨大版本升级Angular时需要验证兼容性。

配置完成后模板内直接写对应协议的链接即可,不会被自动添加unsafe前缀:

<a href="whatsapp://send?text=测试内容">打开WhatsApp</a>
<a href="fb-messenger://user/123456">打开Messenger</a>

方案二:全局a标签处理指令(兼容性最优)

完全使用Angular公开API实现,无版本兼容风险:

  1. 新建全局指令
import { Directive, ElementRef, Input, OnInit } from '@angular/core';
import { DomSanitizer } from '@angular/platform-browser';

@Directive({
  selector: 'a[href]' // 匹配所有带href属性的a标签
})
export class SafeHrefDirective implements OnInit {
  @Input() href!: string;
  // 自定义白名单协议正则
  private allowedProtocols = /^\s*(whatsapp|fb-messenger|sms|tel|mailto):/i;

  constructor(
    private el: ElementRef<HTMLAnchorElement>,
    private sanitizer: DomSanitizer
  ) {}

  ngOnInit(): void {
    if (this.allowedProtocols.test(this.href)) {
      // 跳过安全校验直接赋值href
      this.el.nativeElement.href = this.href;
    }
  }
}
  1. 在根模块AppModule的declarations数组中声明该指令,即可全局生效。

内容的提问来源于stack exchange,提问作者b_it_s

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.04 21:54:03