[英]Replace string with HTML equivalent. Apart from <a> tags
我怎么能去替换一个string
:
Hello my name is <a href='/max'>max</a>!
<script>alert("DANGEROUS SCRIPT INJECTION");</script>
同
Hello my name is <a href='/max'>max</a>!
<script>alert("DANGEROUS SCRIPT INJECTION");</script>
我可以轻松地将所有<
, >
替换为<
, >
有:
string = string.replace(/</g, "<").replace(/>/g, ">");
但我仍然希望能够拥有<a>
链接。
我还研究了使用以下方法防止脚本注入:
var html = $(string.bold());
html.find('script').remove();
但我希望能够仍然阅读脚本标签而不是删除它们。
解决此问题的一种方法是使用具有严格的后视模式的正则表达式,该模式仅允许非常接近某种格式的锚点。
假设您只想允许完全遵循此示例的链接:
<a href="http://host.domain/path?query#anchor">text</a>
和
<a href="https://host.domain/path?query#anchor">text</a>
构建一个正则表达式,仅匹配此有效模式后面的“<”字符(负向lookbehind):
<(?!a href="https?:\/\/\w[\w.-\/\?#]+">\w+<\/a>)
与该正则表达式的一个问题是,如果你匹配它的整个字符串时, <
仍将匹配关闭a
元件( </a>
所以如果更换每一比赛用<
毕竟你会破坏锚。
您可以通过附加否定后备替代方案来允许所有结束</a>
代码:
<(?!a href="https?:\/\/\w[\w.-\/\?#]+">\w+<\/a>|\/a>)
也许其他人对该子问题有更好的解决方案。
这是最后的string.replace:
string.replace(/<(?!a href="https?:\/\/\w[\w.-\/\?#]+">\w+<\/a>|\/a>)/g, '<');
注意:所有这些输入检查必须始终在服务器端完成 ,在客户端,检查可以简单地避开,并且即使进行检查,您也会将恶意数据发送到您的服务器。
这段代码应该可以解决问题。 您可以在数组allowedTagNames
添加要作为HTML标记传递的其他标记名称。
// input
var html = "Hello my name is <a href='/max'>max</a>! <script>alert('DANGEROUS SCRIPT INJECTION');</script>";
var allowedTagNames = ["a"];
// output
var processedHTML = "";
var processingStart = 0;
// this block finds the next tag and processes it
while (true) {
var tagStart = html.indexOf("<", processingStart);
if (tagStart === -1) { break; }
var tagEnd = html.indexOf(">", tagStart);
if (tagEnd === -1) { break; }
var tagNameStart = tagStart + 1;
if (html[tagNameStart] === "/") {
// for closing tags
++tagNameStart;
}
// we expect there to be either a whitespace or a > after the tagName
var tagNameEnd = html.indexOf(" ", tagNameStart);
if (tagNameEnd === -1 || tagNameEnd > tagEnd) {
tagNameEnd = tagEnd;
}
var tagName = html.slice(tagNameStart, tagNameEnd);
// copy in text which is between this tag and the end of last tag
processedHTML += html.slice(processingStart, tagStart);
if (allowedTagNames.indexOf(tagName) === -1) {
processedHTML += "<" + html.slice(tagStart + 1, tagEnd) + ">";
} else {
processedHTML += html.slice(tagStart, tagEnd + 1);
}
processingStart = tagEnd + 1;
}
// copy the rest of input which wasn't processed
processedHTML += html.slice(processingStart);
注意:如果标签的属性中有<
或>
,它将无法工作。 例如: <a href=">">
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.