首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >纯js中的decodeURIComponent Polyfill

纯js中的decodeURIComponent Polyfill
EN

Stack Overflow用户
提问于 2018-12-30 20:47:46
回答 1查看 442关注 0票数 2

我知道每个已知的浏览器都支持"decodeURIComponent“,但我试图通过多填充来更好地理解它。

有许多用于AtobBtoa...的多填充。但是由于某种原因,我没有找到任何用于"decodeURIComponent“的polyfill。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2018-12-31 01:43:07

由于自ES3以来一直支持decodeURIComponent,因此没有多边形填充。

EcmaScript语言规范的"URI Handling Function Properties"一节定义了解码URI的算法(Decode)。它是由decodeURIdecodeURIComponent调用的内部函数。后两个函数实际上是Decode的简单包装器,只是不同之处在于哪些字符被认为是“保留的”。对于decodeURIComponent,这很简单:没有保留字符。

我在这里根据这些规范实现了DecodedecodeURIComponent

代码语言:javascript
复制
function Decode(string, reservedSet) {
    const strLen = string.length;
    let result = "";
    for (let k = 0; k < strLen; k++) {
        let chr = string[k];
        let str = chr;
        if (chr === '%') {
            const start = k;
            let byte = +`0x${string.slice(k+1, k+3)}`;
            if (Number.isNaN(byte) || k + 2 >= strLen) throw new URIError;
            k += 2;
            if (byte < 0x80) {
                chr = String.fromCharCode(byte);
                str = reservedSet.includes(chr) ? string.slice(start, k + 1) : chr;
            } else { // the most significant bit in byte is 1
                let n = Math.clz32(byte ^ 0xFF) - 24; // Position of first right-most 10 in binary
                if (n < 2 || n > 4) throw new URIError;
                let value = byte & (0x3F >> n);
                if (k + (3 * (n - 1)) >= strLen) throw new URIError;
                for (let j = 1; j < n; j++) {
                    if (string[++k] !== '%') throw new URIError;
                    let byte = +`0x${string.slice(k+1, k+3)}`;
                    if (Number.isNaN(byte) || ((byte & 0xC0) != 0x80)) throw new URIError;
                    k += 2;
                    value = (value<<6) + (byte & 0x3F);
                }
                if (value >= 0xD800 && value < 0xE000 || value >= 0x110000) throw new URIError; 
                if (value < 0x10000) {
                    chr = String.fromCharCode(value);
                    str = reservedSet.includes(chr) ? string.slice(start, k + 1) : chr;
                } else { // value is ≥ 0x10000
                    const low = ((value - 0x10000) & 0x3FF) + 0xDC00;
                    const high = (((value - 0x10000) >> 10) & 0x3FF) + 0xD800;
                    str = String.fromCharCode(high) + String.fromCharCode(low);
                }
            }
        }
        result += str;
    }
    return result;
}

function decodeURIComponent(encoded) {
    return Decode(encoded.toString(), "");
}

// Demo
const test = "a€=#;?ñà?x";
console.log("test: " + test);
const encoded = encodeURIComponent(test);
console.log("encoded: " + encoded);
const decoded = decodeURIComponent(encoded);
console.log("decoded: " + decoded);

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/53977714

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档