我有一些我正在处理的遗留代码(所以不,我不能只使用带有编码文件名组件的 URL),允许用户从我们的网站下载文件。由于我们的文件名通常使用多种不同的语言,它们都以 UTF-8 格式存储。我编写了一些代码来处理将 RFC5987 转换为正确的 filename* 参数。在我有一个包含非 ascii 字符的文件名和空格。根据 RFC,空格字符不是 attr_char 的一部分,因此它被编码为 %20。我有新版本的 Chrome 和 Firefox,它们都在下载时转换为 %20 到 +。我尝试不编码空间并将编码的文件名放在引号中并得到相同的结果。我已经嗅探了来自服务器的响应,以验证 servlet 容器没有与我的标头混淆,并且它们对我来说看起来是正确的。RFC 甚至有包含 %20 的示例。我是否遗漏了什么,或者所有这些浏览器都有与此相关的错误?
提前谢谢了。我用来编码文件名的代码如下。
彼得
public static boolean bcsrch(final char[] chars, final char c) {
final int len = chars.length;
int base = 0;
int last = len - 1; /* Last element in table */
int p;
while (last >= base) {
p = base + ((last - base) >> 1);
if (c == chars[p])
return true; /* Key found */
else if (c < chars[p])
last = p - 1;
else
base = p + 1;
}
return false; /* Key not found */
}
public static String rfc5987_encode(final String s) {
final int len = s.length();
final StringBuilder sb = new StringBuilder(len << 1);
final char[] digits = {'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'};
final char[] attr_char = {'!','#','$','&','\'','+','-','.','0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z','^','_','a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z','|', '~'};
for (int i = 0; i < len; ++i) {
final char c = s.charAt(i);
if (bcsrch(attr_char, c))
sb.append(c);
else {
final char[] encoded = {'%', 0, 0};
encoded[1] = digits[0x0f & (c >>> 4)];
encoded[2] = digits[c & 0x0f];
sb.append(encoded);
}
}
return sb.toString();
}
更新
这是我在评论中提到的带有空格的中文文件的下载对话框的屏幕截图。