【问题标题】:Multipart/form-data and UTF-8 in a ASP Classic applicationASP Classic 应用程序中的 Multipart/form-data 和 UTF-8
【发布时间】:2010-12-15 02:16:40
【问题描述】:

我有一个我真的不明白的问题。 我正在尝试在 asp 经典应用程序中上传文件,而不使用外部组件。我还想发布一些将存储在数据库中的文本。 文件上传完美,我用的是这段代码:Upload Files Without COM v3 by Lewis E. Moten III

问题在于其他表单输入字段。我使用的是 UTF-8,但它们最终不是 UTF-8。即如果我使用 Response.Write 将瑞典字符 å ä 和 ö 打印出来,它们将显示为问号。

我已将文件保存为 UTF-8(带有 BOM),我添加了元标记来告诉页面它是 UTF-8。我已经设置了 Response.CharSet = "UTF-8"。

从二进制转换为字符串的函数看起来像这样(这是我能想到的唯一可能出错的地方,因为 cmets 说它提取 ANSI 字符,但我认为它应该提取 Unicode 字符):

Private Function CStrU(ByRef pstrANSI)

    ' Converts an ANSI string to Unicode
    ' Best used for small strings

    Dim llngLength ' Length of ANSI string
    Dim llngIndex ' Current position

    ' determine length
    llngLength = LenB(pstrANSI)

    ' Loop through each character
    For llngIndex = 1 To llngLength

        ' Pull out ANSI character
        ' Get Ascii value of ANSI character
        ' Get Unicode Character from Ascii
        ' Append character to results
        CStrU = CStrU & Chr(AscB(MidB(pstrANSI, llngIndex, 1)))

    Next

End Function

我创建了一个测试 asp 页面 (multiparttest.asp) 来复制它,需要从 Lewis E. Moten 上传的内容才能使其工作(我已将他的文件添加到名为 upload 的子目录中)。

<%Response.CharSet = "UTF-8" %>
<!--#INCLUDE FILE="upload/clsUpload.asp"-->
<html>
    <head>
        <title>Test</title>
        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
    </head>
    <body>
        <%
        Set objUpload = New clsUpload
        Response.Write( objUpload.Fields("testInput").Value )
        %>
        <form method="post" enctype="multipart/form-data" action="multiparttest.asp">
            <input type="text" name="testInput" />
            <input type="submit" value="submit" />
        </form>

    </body>
</html>

我已经在 Firefox 中使用 LiveHTTP 标头捕获了请求,并将其保存为 UTF-8 文件,瑞典语字符看起来应该是应该的(它们在 LiveHTTP 标头 GUI 中看起来不太好,但我猜它自己的 GUI 没有使用正确的编码)。这是 POST 请求的样子:

http://localhost/testsite/multiparttest.asp

POST /testsite/multiparttest.asp HTTP/1.1
Host: localhost
User-Agent: Mozilla/5.0 (Windows; U; Windows NT 6.0; en-US; rv:1.9.1.5) Gecko/20091102 Firefox/3.5.5 (.NET CLR 3.5.30729)
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-us,en;q=0.5
Accept-Encoding: gzip,deflate
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7
Keep-Alive: 300
Connection: keep-alive
Referer: http://localhost/testsite/multiparttest.asp
Cookie: ASPSESSIONIDASBBRBTT=GLDJDBJALAMJFBFBDCCIONHF; ASPSESSIONIDAQABQBTT=DIPHILKAIICKJOIAIMILAMGE; ASPSESSIONIDCSABTCQS=KMHBLBLABKHCBGPNLMCIPPNJ
Content-Type: multipart/form-data; boundary=---------------------------7391102023625
Content-Length: 150
-----------------------------7391102023625
Content-Disposition: form-data; name="testInput"

åäö
-----------------------------7391102023625--

HTTP/1.x 200 OK
Cache-Control: private
Content-Length: 548
Content-Type: text/html; Charset=UTF-8
Server: Microsoft-IIS/7.0
X-Powered-By: ASP.NET
Date: Tue, 10 Nov 2009 14:20:17 GMT
----------------------------------------------------------

感谢您对本课程的任何帮助!

编辑 10/11:

我尝试将所有这些添加到 asp 文件的顶部,因为我在其他地方发现了关于这个问题的不同建议,但没有不同的结果..

<%@Language=VBScript codepage=65001 %>
<%Response.ContentType="text/html"%>
<%Response.Charset="UTF-8"%>
<%Session.CodePage=65001%>

编辑 11/11:

这个问题似乎是相关的,UTF-8 text is garbled when form is posted as multipart/form-data。但他们不使用 ASP 或 IIS。是否可以在 IIS 中为多部分/表单数据设置某种字符编码?我正在使用 IIS7。也许我的请求毕竟有错误的编码? (我现在真的迷失在字符编码的世界里了)

【问题讨论】:

    标签: iis-7 asp-classic character-encoding forms multipartform-data


    【解决方案1】:

    您对 CStrU 的分析是正确的。它假定客户端正在发送单字节 ANSI 字符。它还假设客户端使用的代码页和运行 VBScript 的语言环境相同。

    使用 UTF-8 时,CStrU 所做的假设总是不正确的。据我所知,没有一个使用 65001 作为其代码页的语言环境(我认为有一两个使用 65000,但那又是不同的)。

    这是一个假设文本为 UTF-8 格式的替换函数:-

     Private Function CStrU(ByRef pstrANSI)
    
      Dim llngLength '' # Length of ANSI string
      Dim llngIndex '' # Current position
      Dim bytVal
      Dim intChar
    
      '' # determine length
      llngLength = LenB(pstrANSI)
    
      '' # Loop through each character
      llngIndex = 1
      Do While llngIndex <= llngLength
    
       bytVal = AscB(MidB(pstrANSI, llngIndex, 1))
       llngIndex = llngIndex + 1
    
       If bytVal < &h80 Then
        intChar = bytVal
       ElseIf bytVal < &hE0 Then
    
        intChar = (bytVal And &h1F) * &h40
    
        bytVal =  AscB(MidB(pstrANSI, llngIndex, 1))
        llngIndex = llngIndex + 1
    
        intChar = intChar + (bytVal And &h3f)
    
       ElseIf bytVal < &hF0 Then
    
        intChar = (bytVal And &hF) * &h1000
    
        bytVal =  AscB(MidB(pstrANSI, llngIndex, 1))
        llngIndex = llngIndex + 1
    
        intChar = intChar + (bytVal And &h3F) * &h40
    
        bytVal =  AscB(MidB(pstrANSI, llngIndex, 1))
        llngIndex = llngIndex + 1
    
        intChar = intChar + (bytVal And &h3F)
    
       Else
        intChar = &hBF
       End If
    
       CStrU = CStrU & ChrW(intChar)
      Loop
    
     End Function
    

    请注意,随着 CStrU 针对 UTF-8 进行了更正,您的示例页面的输出现在看起来是错误的。将文件的 Codepage 设置为 65001 的建议也是一项要求。由于您将发送到客户端的 CharSet 设置为“UTF-8”,因此您还需要告诉 ASP 在编码使用 Response.Write 编写的文本时使用 UTF-8 代码页。

    【讨论】:

    • 这是很久以前的答案对于遗留项目仍然派上用场的案例之一。
    【解决方案2】:

    我不知道这是否有任何帮助,但我使用了一些 classic ASP 代码来使用 SWFUpload 实用程序(允许批量上传多个文件的 Flash 插件)。

    ASP 示例代码包括一些整理字节/Unicode 解码的综合代码,看起来与您提到的关于 chr(AscB(MidB(... - 也许看到第二个示例可能会阐明您的问题。

    【讨论】:

    • 他们似乎使用相同的函数,outPut = outPut & Chr(AscB(MidB(binString, i, 1))) 奇怪,也许我做错了什么。。
    【解决方案3】:

    “回到过去”,我用过ASPUpload。购买比花时间处理表单数据更便宜。有点像 ASP.NET,它使常规字段和上传的文件都可用于查询,但它确实 (IIRC) 破坏了 old 表单对象 - 即,一旦您从 ASPUpload 读取,输入流将被消耗,并且尝试使用 常规 表单输入将失败。

    您可以在同一个应用程序中使用这两种方法 - 只是不能在同一个页面请求期间同时使用这两种方法;基本上选择一个或另一个(通常基于传入的 MIME)。

    【讨论】:

    • 我们实际上使用过一次 ASPUpload,但由于我们总是忘记在客户安装时安装该组件,因此不再使用它。
    • @Marc:上传文件时,旧的表单输入无论如何都会被破坏。 ASP Form 对象不知道如何处理多部分正文,因此即使您自己没有使用输入流,Form 对象仍然无用。
    • 那是很久以前的事了——也许我的意思是,如果您尝试先阅读 ASP 表单,那么 ASPUpload 会不高兴?无论哪种方式:不要在同一个请求上同时尝试;-p
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-06-07
    • 2011-04-29
    • 2018-06-11
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多