首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >encodeURIComponent抛出异常

encodeURIComponent抛出异常
EN

Stack Overflow用户
提问于 2013-06-01 02:11:29
回答 1查看 3.1K关注 0票数 3

我正在使用用户提供的输入在encodeURIComponent函数的帮助下以编程方式构建一个URI。但是,当用户输入无效的unicode字符(例如U+DFFF)时,该函数会抛出一个异常,其中包含以下消息:

要编码的URI包含无效字符。

我在MSDN上查过这个,但这并没有告诉我任何我还不知道的事情。

若要更正此错误,请执行以下操作

  • 确保要编码的字符串只包含有效的Unicode序列。

我的问题是,在我将所有无效的Unicode序列传递给encodeURIComponent函数之前,是否有一种方法可以对用户提供的输入进行消毒以删除所有无效的Unicode序列?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2013-06-14 13:01:08

采用编程方法来发现答案,唯一出现问题的范围是\ud800-udfff,即高和低代孕者的范围:

代码语言:javascript
复制
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]/

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

代码语言:javascript
复制
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扩展(急剧地)超出其原来的最大字符数):

代码语言:javascript
复制
alert(encodeURIComponent('\uD800\uDC00')); // ok
alert(encodeURIComponent('\uD800')); // not ok
alert(encodeURIComponent('\uDC00')); // not ok either

因此,如果你想走简单的路线并阻止代孕者,这只是一个问题:

代码语言:javascript
复制
urlPart = urlPart.replace(/[\ud800-\udfff]/g, '');

如果要删除不匹配(无效)代理项,同时允许代理项对(这是合法序列,但字符很少需要),则可以执行以下操作:

代码语言:javascript
复制
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有负面效果的话,这个函数就不会那么难看了.

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

https://stackoverflow.com/questions/16868415

复制
相关文章

相似问题

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