javascript - Java URI 转义器,其工作方式类似于 Javascript 的 unescape

标签 javascript java escaping urldecode unescapestring

我有一个类似 http://google.com/search/q=<%= name %> 的字符串.

我无法控制的第三方 js 库正在将其转义为 "http://google.com/search/q=%3C%=%20name%20%%3E"

哪个Javascript可以成功反转义为原始字符串

unescape("http://google.com/search/q=%3C%=%20name%20%%3E")

但是 Java 的 URLDecode.decode("http://google.com/search/q=%3C%=%20name%20%%3E")抛出 IllegalArgumentException因为未转义文字 %字符串中的字符当然是正确的并且符合规范,但这会使服务器端处理变得复杂。

在我尝试使用正则表达式修复服务器端的错误 JS 转义之前(因为如前所述,我无法修改 JS 端),我想知道是否有更宽松的 Java URL/URI 解码API 的工作方式与 Javascript 的 unescape 相同,即忽略独立的“%”字符,只解码可解码的内容。

最佳答案

我快速浏览了一些 Apache 库并遇到了同样的问题。有趣的是,当我跟进 EMCAScript 语言规范时,我发现了 unescape() 函数的伪代码。你可以在 https://tc39.github.io/ecma262/#sec-unescape-string 看到这个

很容易将它的简单实现放在一起(见下文),至少对于您问题中的示例,输出匹配。

现在这段代码没有经过任何优化,我也没有考虑过字符编码是否相关,但与尝试使用 Regex 解决问题相比,这可能是一种更轻松的方法。

public static String unescape(String s) {
    StringBuilder r = new StringBuilder();
    for (int i = 0; i < s.length();) {
        if (s.charAt(i) == '%') {
            if (looksLikeUnicode(s, i)) {
                r.append((char) fromHex(s, i + 2, i + 5));
                i += 6;
                continue;
            }
            if (looksLikeAscii(s, i)) {
                r.append((char) fromHex(s, i + 1, i + 2));
                i += 3;
                continue;
            }
        }
        r.append(s.charAt(i));
        i += 1;
    }
    return r.toString();
}

private static boolean looksLikeUnicode(String s, int i) {
    return (i + 5 < s.length()) && (s.charAt(i + 1) == 'u') && areHexDigits(s, i + 2, i + 5);
}

private static boolean looksLikeAscii(String s, int i) {
    return (i + 2 < s.length()) && areHexDigits(s, i + 1, i + 2);
}

private static boolean areHexDigits(String s, int from, int to) {
    for (int i = from; i <= to; ++i) {
        if (isNotHexDigit(s.charAt(i))) {
            return false;
        }
    }
    return true;
}

private static boolean isHexDigit(char c) {
    return (c >= '0' && c <= '9') || (c >= 'A' && c <= 'F') || (c >= 'a' && c <= 'f');
}

private static boolean isNotHexDigit(char c) {
    return !isHexDigit(c);
}

private static int fromHex(String s, int from, int to) {
    return Integer.parseInt(s.substring(from, to + 1), 16);
}

关于javascript - Java URI 转义器,其工作方式类似于 Javascript 的 unescape,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47141427/

相关文章:

javascript - 如果在没有警报的情况下使用,Jquery setTimeout 将不起作用

java - 使用 spring-amqp ListenerContainer 关闭应用程序会挂起或需要很长时间

java - Java 不支持枚举上的协变返回类型吗?

browser - 手机浏览 URL 时转义与号 (&) 在 ASP.NET MVC 中开发?

mysql - 使用 MySQL 搜索 : How to escape wildcards

javascript - 在 'body' 标签末尾添加文本/HTML

javascript - 事件类未打开 JS 导航点

javascript - meteor : Clear a field

java - arraylist java 宠物名称和芯片编号

python - 如何将逗号分隔的字符串解析为列表(警告)?