我需要一种将数字 HTML 实体转换为等效的纯文本字符的方法。比如我想转实体:
é
进入角色:
é
通过一些谷歌搜索,我发现了一个名为HtmlUnEditFormat的函数,但这个函数只转换命名实体。有没有办法在 ColdFusion 中解码数字实体?
我需要一种将数字 HTML 实体转换为等效的纯文本字符的方法。比如我想转实体:
é
进入角色:
é
通过一些谷歌搜索,我发现了一个名为HtmlUnEditFormat的函数,但这个函数只转换命名实体。有没有办法在 ColdFusion 中解码数字实体?
感谢 Todd Sharp 指出了一种非常简单的方法来做到这一点,使用 Apache Commons StringEscapeUtils 库,它与 CF(和 Railo)一起打包,所以你可以这样做:
<cfset Entity = "&##0233;" />
<cfset StrEscUtils = createObject("java", "org.apache.commons.lang.StringEscapeUtils") />
<cfset Character = StrEscUtils.unescapeHTML(Entity) />
该链接函数很讨厌-无需明确命名它们,并且正如您所说,它不做数字。
更简单的是让 CF 为您完成工作 - 使用以下XmlParse
功能:
<cffunction name="decodeHtmlEntity" returntype="String" output="false">
<cfargument name="Entity" type="String" hint="&##<number>; or &<name>;" />
<cfreturn XmlParse('<xml>#Arguments.Entity#</xml>').XmlRoot.XmlText />
</cffunction>
那个适用于Railo,但我不记得CF是否支持该语法,因此您可能需要将其更改为:
<cffunction name="decodeHtmlEntity" returntype="String" output="false">
<cfargument name="Entity" type="String" hint="&##<number>; or &<name>;" />
<cfset var XmlDoc = XmlParse('<xml>#Arguments.Entity#</xml>') />
<cfreturn XmlDoc.XmlRoot.XmlText />
</cffunction>
这是另一个函数,它将解码字符串中的所有数字 html 字符实体。它不依赖于 xml 解析,因此它适用于包含不平衡 xml 标签的字符串。如果字符串具有大量实体,则效率不高,但如果没有/很少,那就很好了。我只在 Railo 上测试过这个,而不是 AdobeCF。
<cffunction name="decodeHtmlEntities" returntype="String" output="false">
<cfargument name="s" type="String"/>
<cfset var LOCAL = {f = ReFind("&##([0-9]+);", ARGUMENTS.s, 1, true), map={}}>
<cfloop condition="LOCAL.f.pos[1] GT 0">
<cfset LOCAL.map[mid(ARGUMENTS.s, LOCAL.f.pos[1], LOCAL.f.len[1])] = chr(mid(ARGUMENTS.s, LOCAL.f.pos[2], LOCAL.f.len[2]))>
<cfset LOCAL.f = ReFind("&##([0-9]+);", ARGUMENTS.s, LOCAL.f.pos[1]+LOCAL.f.len[1], true)>
</cfloop>
<cfloop collection=#LOCAL.map# item="LOCAL.key">
<cfset ARGUMENTS.s = Replace(ARGUMENTS.s, LOCAL.key, LOCAL.map[LOCAL.key], "all")>
</cfloop>
<cfreturn ARGUMENTS.s />
</cffunction>
自己编写一个代码应该很容易。只需编辑您找到的 HtmlUNEditFormat() 函数,将它们包含在 lEntities 和 lEntitiesChars 的末尾。
我在使用一种方法时发现了这个问题,根据黑盒原理,该方法不能相信传入的字符串是 HTML 实体编码的还是不是。
我已经修改了 Peter Boughton 的函数,以便它可以安全地用于尚未使用 HTML 实体处理的字符串。(这似乎唯一重要的时候是目标字符串中出现松散的 & 符号 - 即“Cats & Dogs”。)这个修改后的版本也会在任何不可预见的 XML 解析错误中稍微失败。
<cffunction name="decodeHtmlEntity" returntype="string" output="false">
<cfargument name="str" type="string" hint="&##<number>; or &<name>;" />
<cfset var XML = '<xml>#arguments.str#</xml>' />
<cfset var XMLDoc = '' />
<!--- ampersands that aren't pre-encoded as entities cause errors --->
<cfset XML = REReplace(XML, '&(?!(\##\d{1,3}|\w+);)', '&', 'all') />
<cftry>
<cfset XMLDoc = XmlParse(XML) />
<cfreturn XMLDoc.XMLRoot.XMLText />
<cfcatch>
<cfreturn arguments.str />
</cfcatch>
</cftry>
</cffunction>
这将安全地支持以下用例:
<cffunction name="notifySomeoneWhoCares" access="private" returntype="void">
<cfargument name="str" type="string" required="true"
hint="String of unknown preprocessing" />
<cfmail from="process@domain.com" to="someoneWhoCares@domain.com"
subject="Comments from Web User" format="html">
Some Web User Spoke Thus:<br />
<cfoutput>#HTMLEditFormat(decodeHTMLEntity(arguments.str))#</cfoutput>
</cfmail>
</cffunction>
现在,此功能对于确保 Web 提交的内容在通过电子邮件发送或提交到数据库表之前是实体安全的(想想 XSS)非常有用。
希望这可以帮助。