#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;
сработал как заклинание. В конечном итоге я расширю его, чтобы также удалить теги сценариев. Спасибо!