【问题标题】:HTML Encode & URLsHTML 编码和 URL
【发布时间】:2011-12-18 05:01:55
【问题描述】:

我有一个必须从 html 代码中删除的输入字符串,因此我使用默认的 .Net 函数 .HtmlEncode() 来转义所有危险字符。

现在我正在尝试通过正则表达式将输入字符串中的 URL 替换为 HREF 锚点。

问题是,当我在调用 .HtmlEncode() 之前“链接”URL 时,锚标记会丢失,这是合乎逻辑的。但是当我在调用 .HtmlEncode() 之后进行链接时,某些 url 格式错误,因为它们包含危险字符?

这似乎是一个鸡蛋问题,应该如何解决?

例子:

输入字符串:

See http://example.com/q=1&x=2

预期结果:

See <a href="http://example.com/q=1&x=2">http://example.com/q=1&amp;x=2</a>

先做HtmlEncode,后调用Linkify:

See <a href="http://example.com/q=1&amp;x=2">http://example.com/q=1&amp;x=2</a>

先做Linkify,后调用HtmlEncode:

See &lt;a href=&quot;http://example.com/q=1&amp;x=2&quot;&gt;http://example.com/q=1&amp;x=2&lt;/a&gt;

我目前使用的解决方案是对正则表达式 (linkify) 找到的所有匹配项调用 .HtmlDecode(),但这不是 100% 万无一失的,因为理论上有效的 URL 可能包含像 &amp;amp; 这样的模式解码,但不应该。

【问题讨论】:

  • 也许包括一个简单的例子?目前尚不清楚链接过程究竟需要什么。
  • 这个“linkify”正则表达式实用程序是什么?
  • @JeremyStein 就是这样一个正则表达式:codinghorror.com/blog/2008/10/the-problem-with-urls.html
  • @Joshua 该示例没有替换部分。这是一种很好的匹配方式,但不足以替换。我会发布答案...

标签: .net regex escaping html-encode linkify


【解决方案1】:

你不能用正则表达式替换来做到这一点。您需要通过 urlencode 运行 href 属性,并通过 htmlencode 运行链接文本。

【讨论】:

  • 我当前的解决方案是在字符串上运行 HtmlEncode(),执行 RegEx.Replace(),然后在 HREF 上运行 HtmlDecode。这适用于 99% 的情况,但理论上有效链接有可能包含 HTML 编码参数,这些参数不应被解码。但我以前从未见过这样的 URL ;)
  • 我不明白您如何编写代码来识别 href 属性以调用 HtmlDecode,但您无法编写代码来识别链接并正确处理它们。
  • 如果您向我们展示您正在使用的代码,也许我会明白。
【解决方案2】:

这似乎是一场等待发生的跨站点脚本攻击。

Test link to google.

我见过的将用户输入转换为 HTML 标记的大多数方法都使用某种“保留”的自定义非 HTML 序列来完成此操作,例如,上面的链接在 Stack Overflow 编辑器中实际上如下所示:

[Test link to google.][1]    

  [1]: http://www.google.com

其他丰富的 UI 界面做类似的事情。它不是 HTML,但会被解析并稍后输出为 HTML。 我不确定这种方法是否适用于您的情况,但它可能是值得的。您通常希望避免让某人能够将原始 HTML 输入到您的应用程序中,除非您信任他们(并且由于您的 HtmlEncoding 其中一些,看起来您并不真正信任他们)。

【讨论】:

  • 我已经允许通过 ubb 代码使用字体样式和换行符,例如 [b] 用于粗体,[br] 用于中断,所以我可以添加 [url] 作为 URL 的要求,但它只会帮助在纯文本中找到 URL,而不是防止 HtmlEncode() 搞砸了;)我可以用 Base64 之类的东西临时对它们进行编码,执行 HtmlEncode,然后将它们解码回来,但它没有似乎不是一个合适的解决方案。
  • 我正在阅读一本 Drupal 书籍,发现有一个我称之为“保留的自定义非 HTML 序列”的伪标准——BBCode。我快速搜索了 .NET BBCode 并得出以下结论:eksith.wordpress.com/2009/01/14/aspnet-bbcode-c 该页面上还有一个标题为“更好的替代方案”的链接,看起来与您正在寻找的解决方案相符。
【解决方案3】:

您必须区别对待普通文本和链接。所以,首先将输入分成几部分:

If you don't believe me that 1 < 2, see http://example.com/q=1&x=2

变成一个有两个成员的集合:

{ "If you don't believe me that 1 < 2, see ", "http://example.com/q=1&x=2" }

您对第一个进行编码并从第二个中创建一个链接,只对链接的文本进行编码:

{
    "If you don't believe me that 1 &lt; 2, see ",
    "<a href=\"http://example.com/q=1&x=2\">http://example.com/q=1&amp;x=2</a>"
}

然后将结果加入最终结果中。

但是,如果您使用为生成 HTML 而设计的库,也许会更好。 Html Agility Pack 或 ASP.NET,取决于您的需要。

【讨论】:

  • Linkify 函数是一个单一的正则表达式,如果我想使用你的解决方法,我必须自己编写一个非常复杂的链接检测函数。而且我不生成 HTML,它是来自表单的用户输入,所以我不能使用任何库来生成 HTML。
  • 我不明白,你为什么不能使用图书馆?
  • 该库用于解析 html 输入,所以我不能使用它,因为我的输入是纯文本,它不应该包含任何 HTML。我唯一需要做的就是将(纯文本)链接转换为 html 锚。
猜你喜欢
  • 1970-01-01
  • 2010-12-21
  • 1970-01-01
  • 2011-08-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-09-29
相关资源
最近更新 更多