javascript - 纯js中的decodeURIComponent Polyfill
问题描述
我知道decodeURIComponent
每个已知的浏览器都支持“”,但我试图通过填充它来更好地理解它。
有很多polyfills Atob
,Btoa
....但是由于某种原因我没有找到任何用于“ decodeURIComponent
”的polyfill,为什么?
解决方案
没有 polyfill,因为decodeURIComponent
从 ES3 开始支持。
EcmaScript 语言规范的“URI 处理函数属性”部分定义了解码 URI ( Decode
) 的算法。它是一个内部函数,由decodeURI
和调用decodeURIComponent
。后两个函数是非常简单的包装器Decode
,只是在哪些字符被认为是“保留”方面有所不同。因为decodeURIComponent
它很简单:没有保留字符。
我在这里实施Decode
并decodeURIComponent
根据这些规范:
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);
推荐阅读
- python - 为什么我的代码打印出我尚未分配的值?
- java - 供应商
> 不能多次迭代 - git - 有没有办法让 GitHub CI 构建 PR 的测试合并,而不是 PR 分支的负责人?
- java - 如何在java中访问类之外的静态块变量
- android - Jetpack 导航:在工具栏中隐藏标签
- python - 基数为 10 的 int() 的无效文字:-django
- pip - 无法在 python 2.6.6 上安装 pip - 缺少依赖项
- node.js - prerender Angular 5 不渲染路线
- node.js - 数据库中字段的Firebase深度增量
- javascript - createBottomTabNavigator:从 tabBar 中只隐藏一个选项卡