在进行POST时,是否需要对表单参数名称进行编码?

时间:2010-12-02 22:25:11

标签: python forms file-upload http-post urllib

快速版:是否需要对使用标准 multipart / form-data 编码发送的“表单”参数的名称进行编码?

更长版本1fichier.com上传表单(上传大文件的服务)使用以下内容指定要上传的文件参数:

<input type="file" name="file[]" size="50" title="Select the files to upload" />

参数的名称是 file [] (注意括号)。

使用LiveHTTPHeaders我看到在Firefox中提交表单时,参数是这样发送的(即带括号)。但是,对于我用Python编写的program,我使用poster模块来使用标准 multipart / form-data 编码上传文件。如果我用括号输入参数名称,它会像这样发送:

file%5B%5D

在内部,海报使用此功能对参数的名称进行编码:

def encode_and_quote(data):
    """If ``data`` is unicode, return urllib.quote_plus(data.encode("utf-8"))
    otherwise return urllib.quote_plus(data)"""
    if data is None:
        return None

    if isinstance(data, unicode):
        data = data.encode("utf-8")
    return urllib.quote_plus(data)

urllib.quote_plus文档说这只是“在构建查询字符串以进入URL时引用HTML表单值所必需的”。但是这里我们正在进行POST,因此表单值不会进入URL。

那么,它们是否仍需要编码,或者这样做是否是海报的错误?

2 个答案:

答案 0 :(得分:1)

RFC 2388涵盖了多部分/表单数据提交。第3节规定参数名称应为ASCII或按RFC 2047编码。

因此,如果您的POST请求被编码为multipart / form-data(海报正在进行),那么不需要,参数名称不需要以这种方式编码。我建议向作者提交一个错误(咳咳......),他可能愿意在将来的版本中修复它;)

解决方法是直接设置MultipartParam的名称属性,例如

   p.name = 'file[]'

答案 1 :(得分:1)

虽然这个问题实质上已经得到了解答,但我还要详细介绍如何深入了解这些RFC。

RFC 2388 section 3声明需要Content-Disposition标头。即使RFC 2047,也应使用looks like a conflict对非ASCII数据进行编码。 RFC 2183 section 2描述了此Content-disposition标头的格式。 name符合该语法的一般parameter规则,但为此引用了RFC 2045There in section 5.1您发现parameter的右侧是tokenquoted-string。两个产品都没有提到表单名称的任何URL编码格式。但[]位于tspecials,因此它们不能成为token的一部分。所以我们得到

Content-Disposition: form-data; name="file[]"        (correct)
Content-Disposition: form-data; name=file[]          (invalid)
Content-Disposition: form-data; name="file%5B%5D" (wrong name)
Content-Disposition: form-data; name=file%5B%5D   (wrong name)

非ASCII文件名的另一个注意事项:current HTML 5 specification draft要求不以7位安全方式对它们进行编码,而是以整个请求中使用的编码方式传输它们。 A question about non-ascii field names让我今天看到你的这个问题。