免除转义字符串中的字符

时间:2011-08-08 19:06:55

标签: javascript url escaping encodeuricomponent

我有一个小功能,可以从对象中创建URL参数:

function MkArgs(o) {
    var ret = '?';
    for (var i in o) {
        ret += i + '=' + escape(o[i]) + '&';
    }
    return ret.substr(0, ret.length - 1);
}

我可以这样打电话:

MkArgs({
    protocol: 'wsfederation',
    realm: 'https://www.x.com/',
    fedRes: 'Home/FederationResult',
    context: '~/Home/FAQ',
    version: '1.0',
    callback: '?'
});

产生以下内容:

?protocol=wsfederation&realm=https%3A//www.x.com/&fedRes=Home/FederationResult&context=%7E/Home/FAQ&version=1.0&callback=%3F

一切都很好,除了我不希望最后一个参数转义,即我想要:

callback=?

而不是

callback=%3F

有什么办法可以在字符串中表明吗?我试过'\?'但是没有做到这一点,并且没有找到任何关于如何保护一段字符串免于逃避的引用......

  • ë

5 个答案:

答案 0 :(得分:1)

escape或encodeURIComponent函数没有任何“跳过”某些字符的方法。因此,您可以做的就是避免在不想要或替换不想编码的字符时调用编码函数,调用编码然后再将原始字符放回去。

如果你想跳过转义特定键的整个值,你可以检查一下你不想逃脱的特定键,并按照这样处理:

function MkArgs(o) {
    var ret = '?';
    for (var i in o) {
        var val = o[i];
        if (i != "callback") {
            val = encodeURIComponent(val);
        }
        ret += i + '=' + val + '&';
    }
    return ret.substr(0, ret.length - 1);
}

如果你想跳过某些字符,那么你可以用一些独特的序列替换它们,转义然后把它们放回去:

function MkArgs(o) {
    var ret = '?';
    for (var i in o) {
        var val = o[i];
        if (i == "callback") {
            val = val.replace(/\?/, "--xx--");  // replace with unique sequence
            val = encodeURIComponent(val);
            val = val.replace(/--xx--/, "?");   // put orig characters back
        } else {
            val = encodeURIComponent(val);
        }
        ret += i + '=' + val + '&';
    }
    return ret.substr(0, ret.length - 1);
}

仅供参考,请注意我已使用encodeURIComponent()而不是已弃用的escape(),因为escape()不适用于非ascii字符。

答案 1 :(得分:1)

MkArgs功能是你自己的;将其更改为包含转义机制。不过,我建议不要使用反斜杠。如果这只是你自己的代码,也许就足以引入一个hackish特殊情况。

答案 2 :(得分:1)

这是一个非常特殊的案例。也许你应该改变你的功能:

function MkArgs(o, isJSONP) {
    var ret = '?';
    for (var i in o) {
        var val = o[i];
        val = escape(val);
        ret += i + '=' + val + '&';
    }
    return ret.substr(0, ret.length - 1) + isJSONP ? '&callback=?':'';
}

并称之为:

MkArgs({
  protocol: 'wsfederation',
  realm: 'https://www.x.com/',
  fedRes: 'Home/FederationResult',
  context: '~/Home/FAQ',
  version: '1.0'
}, true);

答案 3 :(得分:0)

function MkArgs(o) {
    var ret = '?';
    var lastEl = '';
    for (var i in o) {
        ret += i + '=' + escape(o[i]) + '&';
        lastEl = o[i];
    }
    return ret.substr(0, ret.length - 1 - lastEl.length) + lastEl;
}

这适用于对象中的最后一个元素。

编辑:似乎在经典的for in循环中,javascript没有精确的顺序,它在对象道具上循环,因此上述解决方案无法保证正常工作。
在这种情况下,您有两个解决方案:

  • 如果你知道要保护哪个属性不被转义,你应该检查循环中的那个道具,特别是不要逃避它:

    for (var i in o) {
         if(i=="myProp")
         // unescape
         else
         // escape
    }
    
  • 如果你现在没有属性,但是你只想在查询中添加最后一个属性,你可以做这样的事情(在构建查询之后):

    var q = MkArgs(o);
    var parts = q.split('=');
    var toUnescape = parts[parts.length-1];
    q = q.substring(0,q.length - toUnescape.length) + unescape(toUnescape);
    

答案 4 :(得分:0)

感谢大家的回复。我最终做的是:

function MkArgs(o) {
    var ret = '?';
    for (var i in o) {
        ret += i;
        if (o[i]) ret += '=' + escape(o[i]);
        ret += '&';
    }
    return ret.substr(0, ret.length - 1);
}

然后称之为:

MkArgs({
    protocol: 'wsfederation',
    realm: 'https://www.x.com/',
    fedRes: 'Home/FederationResult',
    context: '~/Home/FAQ',
    version: '1.0',
    'callback=?': null
});

这样我不会依赖价值观,而是依靠关键来区分。不是很漂亮,但它是我能想到的最好的