在MSXML/ASP中解析UTF-8编码的XML

在MSXML/ASP中解析UTF-8编码的XML,xml,asp-classic,utf-8,msxml,Xml,Asp Classic,Utf 8,Msxml,我在HTTP POST(x-www-form-urlencoded)的接收端,其中一个字段包含XML文档。我需要接收该文档,查看几个元素,并将其存储在数据库中(供以后使用)。 文档采用UTF-8格式(并且具有适当的标题),并且可以包含许多奇怪的字符 当我收到数据时,如下所示: Set xmlDoc = CreateObject("MSXML2.DOMDocument.3.0") xmlDoc.async = False xmlDoc.loadXML(Request.Form("xml")) 我

我在HTTP POST(x-www-form-urlencoded)的接收端,其中一个字段包含XML文档。我需要接收该文档,查看几个元素,并将其存储在数据库中(供以后使用)。 文档采用UTF-8格式(并且具有适当的标题),并且可以包含许多奇怪的字符

当我收到数据时,如下所示:

Set xmlDoc = CreateObject("MSXML2.DOMDocument.3.0")
xmlDoc.async = False
xmlDoc.loadXML(Request.Form("xml"))
我能从DOM文档中挖掘出的所有内容仍然是UTF-8格式。 例如,本文件(大大简化):


ä
总是被当作

<?xml version="1.0" encoding="UTF-8"?>
<data>
 ä
</data>

ä
如果我查看xmlDoc.XML,我会发现:

<?xml version="1.0"?>
<data>
 ä
</data>

ä
它从标题中删除了编码(因为我在VBScript中使用的任何字符串都是“编码不可知”,这有点道理),但它仍然是一个表示UTF-8编码文档的字符序列

这就好像MSXML不关心头中的编码信息一样。是MSXML的问题,还是post数据的编码问题?它是“双重编码”的一种形式,首先是UTF-8(某些字符是用几个字节写入的),然后是URL编码的逐字节(“ä”实际上作为%C3%A4发送)


我不想硬编码任何东西,比如假设它总是UTF-8(因为将来某个时候它很可能是UTF-16)。我也无法对任何其他字符集(如iso-8859-1)进行“硬转换”,因为数据可能包含西里尔语和阿拉伯语字符。我应该如何着手解决这个问题?

选项1

在阅读任何表单字段之前,请修改您的响应。代码页值:-

Response.CodePage = 65001
问题是表单数据的内容没有被接收页面理解为UTF-8编码。因此,将%C3%A4数据视为两个不同的ANSI字符。pages Response.CodePage奇怪地影响了在缺少客户端发送的字符集信息的情况下表单数据的解码方式

选项2

修改源页面上的表单元素。向其添加以下属性:-

<form accept-charset="UTF-8" ...>

这将强制对post中的字符进行UTF-8编码,并使post携带有关所选字符集的数据,从而为服务器提供正确解码数据所需的信息

选项3


最后,我个人的偏好是,不要将XML作为字段值发布到表单中。相反,通过将其他表单字段值作为属性或元素添加到XML中,然后使用
XmlHttpRequest
发布XML来扭转这种局面。对于导航,让服务器返回客户端应该导航到的URL,该URL将包含发布数据的GUID句柄,以便服务器收到请求时可以采取适当的操作。然而,我意识到,这需要做更多的工作,在这种情况下,其他两个选项中的一个应该适合您。

由于这种重写的复杂性,目前几乎可以排除选项3

选项1对我来说似乎很奇怪,响应的代码页应该指示请求发生了什么,但是如果是这样的话,那就这样吧

至于选项2,它实际上不是一个浏览器表单发布,而是一个小型脚本客户端(使用CURL)。由此发送的HTTP头会是什么,可以添加到脚本化请求中


总之,我想这意味着当从字符串加载时,MSXML只会忽略xml头中设置的任何编码。

@ionn:我有点困惑,你是@jstck团队的一员吗?对于选项2,您可以尝试将标题“Accept Charset:UTF-8”添加到正在发送的请求标题中。然而,这也有点奇怪,因为它实际上说明了所需的响应字符集应该是什么。我发现选项1更可靠。我不知道CURL,但在脚本环境中,选项3更可取,尽管CURL可能有所不同。
<form accept-charset="UTF-8" ...>