Исключение символов в экранированной строке - PullRequest
0 голосов
/ 08 августа 2011

У меня есть небольшая функция, которая создает 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

есть ли способ, которым яможете указать что внутри строки?Я попытался '\?', но это не сработало, и я не нашел ссылок на то, как защитить кусок строки от побега ...

  • e

Ответы [ 5 ]

1 голос
/ 08 августа 2011

Функция MkArgs - ваша;измените его, чтобы включить механизм побега.Я бы посоветовал не использовать обратную косую черту.Если это всего лишь ваш собственный код, возможно, этого будет достаточно, чтобы поместить в хакерский особый случай.

1 голос
/ 08 августа 2011

Это довольно особый случай. Может быть, вы должны изменить свою функцию:

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);
1 голос
/ 08 августа 2011

Функции 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.

0 голосов
/ 09 августа 2011

спасибо всем за ответы.я закончил тем, что сделал:

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
});

, поэтому я не полагаюсь на значения, а на ключи, чтобы сделать различие.не очень красиво, но это лучшее, что я мог придумать

0 голосов
/ 08 августа 2011
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;
}

это работает для последнего элемента в объекте.

EDIT : Похоже, что в классическом цикле for in javascript не имеет точного порядка, в которомон зацикливается на объектных подпорках, поэтому вышеупомянутое решение не гарантированно работает.
В этом случае у вас есть 2 решения:

  • Если вы знаете, какое свойство вы хотите «защитить»"из побега, вы должны проверить наличие этого реквизита в цикле и, в частности, не избегать его:

    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);
    
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...