Как удалить/проверить наличие тегов привязки в динамически загружаемом html в Angular JS 11

#javascript #angular

Вопрос:

Так что я новичок в сообществе (долгое время БЫЛ ТАКИМ потребителем). Я работаю над приложением киоска с использованием Angular JS через браузер chromium (режим киоска). Проблема, с которой я столкнулся, заключается в том, что мне нужно включить страницу конфиденциальности и условий предоставления услуг (ToS) на нескольких языках, которая может содержать нежелательные ссылки. Вместо того, чтобы создавать компоненты/страницы для различных языков, все, что у меня есть, — это страница конфиденциальности, которая вызывает api/сервис, и набор файлов в формате html для каждого из языков (эти файлы, скорее всего, будут получены от маркетинговых/юридических групп-и они, вероятно, вытащат его с веб-сайта компании, не удаляя ссылки). Api, по сути, извлекает/обслуживает файл html/body для соответствующего языка.

Интересно, что все остальные страницы останутся на английском языке (США), но конфиденциальность и TOS не могут. Примечание: Киоск также должен работать в автономном режиме (не подключен к Интернету), но может периодически подключаться, если это возможно, для обновления. API и приложение доставляются внутренне (с помощью localhost) приложением/потоком, созданным на основе узла (все они являются частью решения IoT).

Проблема в том, что при загрузке этого динамического html, если html содержит якоря, и пользователь должен был щелкнуть по одному из них, приложение будет перемещаться, и нет клавиатуры мыши для возврата. Очевидное решение состоит в том, чтобы не размещать ссылки в первую очередь, но велика вероятность того, что маркетологи скопируют текст или правила конфиденциальности со своего основного веб-сайта и передадут нам. В каждом файле может быть от 10 до 20 или более ссылок, а для языков может быть около 20 файлов или около того.

Я надеялся использовать угловую схему JS в TypeScript, чтобы посмотреть на динамически изменяемый DOM и удалить или изменить атрибуты href любых и всех тегов привязки, по существу «отключающих» навигацию. Я избегал jQuery напрямую. Я также не хочу трогать/изменять html — файлы-возможно, потребуется также удалить встроенные теги javascript или скриптов.

Я также хотел посмотреть, есть ли способ перехватить событие щелчка на якорях и предотвратить навигацию по чему-либо, что еще не определено в маршрутизаторе приложений.

Наконец, я могу посмотреть на chromium, чтобы предотвратить навигацию по чему — либо, кроме локального хоста, но это кажется неоптимальным.

Любые идеи приветствуются. В компоненте .html…

<div [innerHtml]="htmlData"></div>

В компоненте .ts…

import { DomSanitizer } from '@angular/platform-browser';

:

constructor(public http: HttpClient, private sanitizer: DomSanitizer, public restApi: DeviceApiService) { }

:

this.htmlData = this.sanitizer.bypassSecurityTrustHtml(this.htmlString);

где HtmlString содержит ответ/полезную нагрузку от вызова API (на основе языка) с типом ответа:текст

Я заметил, что bypassSecurityTrustHtml разумно использовать, поскольку источник контента известен. Это также позволяет соответствующим образом отображать встроенный CSS.

пример фрагмента html с разрывами строк и элементами внутри привязки… (вы можете видеть, что это было из офисного документа). Это некрасиво, но справедливо.

 <p class=MsoNormal style='margin-top:0in;margin-right:0in;margin-bottom:6.0pt;margin-left:.5in;background:white'>
            <span style='font-size:9.0pt;line-height:107%;font-family:"Verdana",sans-serif;color:#828282'>
                amp;nbsp; To learn more about
                cookies, please visitamp;nbsp;
            </span><a href="http://www.allaboutcookies.org/">
                <span style='font-size:9.0pt;line-height:107%;font-family:"Verdana",sans-serif;color:#0C8CAA'>
            http://www.allaboutcookies.org</span>
            </a><span style='font-size:9.0pt;line-height:107%;font-family:"Verdana",sans-serif;color:#828282'>.</span>
        </p>
 

Ответ №1:

Поскольку у вас есть необработанная HTML-строка, ваши возможности безграничны. Вы можете использовать регулярные выражения, чтобы удалить внешние ссылки и заменить их тем, что вы сочтете необходимым.

Если регулярное выражение не является жизнеспособным вариантом, вы можете выполнить итерацию по dom и удалить href из тегов привязки.

Вот рабочая демонстрация на stackblitz.

 import { Component, OnInit, VERSION } from '@angular/core';
import { DomSanitizer, SafeHtml } from '@angular/platform-browser';

@Component({
  selector: 'my-app',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent implements OnInit {
  htmlData: SafeHtml;
  formattedHtmlData: SafeHtml;

  constructor(private sanitizer: DomSanitizer) {}

  ngOnInit(): void {
    let htmlString: string = `<div>Some Text</div> <a href="https://google.com">External Link 2</a>`;

    let formattedHtmlString = this.striplinks(htmlString);
    this.htmlData = this.sanitizer.bypassSecurityTrustHtml(htmlString);
    this.formattedHtmlData = this.sanitizer.bypassSecurityTrustHtml(
      formattedHtmlString
    );
  }

  striplinks(text) {
    var re = /<as.*?href=["'](.*?)["']*?>(.*?)</a>/g;
    var str = text;
    var subst = '$2';
    var result = str.replace(re, subst);
    return resu<
  }

removeHrefFromAnchorTags(html) { 
var container = document.createElement('p');
container.innerHTML = html;

var elements = container.getElementsByTagName('*');

for (var i = 0, max = elements.length; i < max; i  ) {
  debugger;
  if (elements[i].tagName === 'A') {
    (elements[i] as HTMLAnchorElement).href = '';
  }
}

return [].map.call( elements, function(node){
    return node.textContent || node.innerText || "";
}).join("");
 

}
}

Комментарии:

1. Должен признать, что это умно. Меня беспокоит только учет различий в допустимом синтаксисе, таких как разрывы строк. (добавлен пример к вопросу). Было бы лучше перемещаться по дому?

2. Обновил пример. Я согласен, что регулярное выражение может быть немного сложным, чтобы охватить все сценарии. Однако с хорошим регулярным выражением, должно быть в состоянии охватить почти все возможные комбинации. Поскольку регулярное выражение не является 100% — ным доказательством ошибки, мы добавили еще один способ итерации dom и удаления href из гиперссылок. В стекблитце мне только что удалось извлечь текст и отобразить его, но вам также придется применить классы css. Это приведет к удалению всех ссылок на теги привязки.

3. Это хоть как-то помогло?

4. Элвин, Да! Спасибо и приношу извинения за задержку с ответом. В итоге я использовал метод removeHrefFromAnchorTags в своей вспомогательной службе утилит (поскольку есть еще один компонент с аналогичной потребностью). Я внес незначительные изменения в: (elements[i] as HTMLAnchorElement).href = 'javascript:void(0);'; и на карте вызов return node.outerHTML; сработал как заклинание. В конечном итоге я расширю его, чтобы также удалить теги сценариев. Спасибо!