encodeURIComponent方法抛出一个异常(encodeURIComponent thro

2019-10-18 05:06发布

我编程的方式构建一个URI用的帮助encodeURIComponent使用用户提供的输入功能。 但是,当用户进入无效的Unicode字符(例如U+DFFF ),该函数将抛出具有以下消息的异常:

的URI将被编码包含无效字符

我看着这件事上MSDN ,但没有告诉我什么我不知道的。

更正此错误

  • 确保将被编码字符串中包含唯一有效的Unicode序列。

我的问题是,有没有办法来净化提供的输入删除所有无效的Unicode序列之前,我把它传递给用户encodeURIComponent的功能?

Answer 1:

以方案办法去发现答案,这打开了任何问题的唯一范围为\ ud800- \ udfff,高和低的代理人的范围:

for (var regex = '/[', firstI = null, lastI = null, i = 0; i <= 65535; i++) {
    try {
        encodeURIComponent(String.fromCharCode(i));
    }
    catch(e) {
        if (firstI !== null) {
            if (i === lastI + 1) {
                lastI++;
            }
            else if (firstI === lastI) {
                regex += '\\u' + firstI.toString(16);
                firstI = lastI = i; 
            }
            else {
                regex += '\\u' + firstI.toString(16) + '-' + '\\u' + lastI.toString(16);
                firstI = lastI = i; 
            }
        }
        else {
            firstI = i;
            lastI = i;
        }        
    }
}

if (firstI === lastI) {
    regex += '\\u' + firstI.toString(16);
}
else {
    regex += '\\u' + firstI.toString(16) + '-' + '\\u' + lastI.toString(16);
}
regex += ']/';
alert(regex);  // /[\ud800-\udfff]/

然后我用一个简单的例子证实了这一点:

for (var i = 0; i <= 65535 && (i <0xD800 || i >0xDFFF ) ; i++) {
    try {
        encodeURIComponent(String.fromCharCode(i));
    }
    catch(e) {
        alert(e); // Doesn't alert
    }
}
alert('ok!');

而这符合MSDN说什么,因为实际上所有的Unicode字符(甚至是有效的Unicode“非字符”)之外的代理人都是有效的Unicode序列。

事实上,你可以筛选出高和低的代理人,但在高低温对使用时,他们成为合法的(因为他们是为了以这种方式被使用,以允许对Unicode的扩大(大幅)超出字符原来的最大数量):

alert(encodeURIComponent('\uD800\uDC00')); // ok
alert(encodeURIComponent('\uD800')); // not ok
alert(encodeURIComponent('\uDC00')); // not ok either

所以,如果你想采取简单的方法和块代理人,它仅仅是一个的事情:

urlPart = urlPart.replace(/[\ud800-\udfff]/g, '');

如果你想去掉无与伦比(无效)的代理人,同时允许代理对(这是合法的序列,但很少曾经需要的字符),你可以做到以下几点:

function stripUnmatchedSurrogates (str) {
    return str.replace(/[\uD800-\uDBFF](?![\uDC00-\uDFFF])/g, '').split('').reverse().join('').replace(/[\uDC00-\uDFFF](?![\uD800-\uDBFF])/g, '').split('').reverse().join('');
}

var urlPart = '\uD801 \uD801\uDC00 \uDC01'
alert(stripUnmatchedSurrogates(urlPart)); // Leaves one valid sequence (representing a single non-BMP character)

如果JavaScript的有负回顾后功能会少了很多丑陋...



文章来源: encodeURIComponent throws an exception