Эквивалентные функции Javascript для Python urllib.quote() и urllib.unquote()

Существуют ли какие-либо эквивалентные функции Javascript для Python urllib.quote() и urllib.unquote()?

Самые близкие, с которыми я столкнулся, это escape(), encodeURI() и encodeURIComponent() (и соответствующие им функции декодирования), но, насколько я могу судить, они не кодируют/декодируют один и тот же набор специальных символов.

Спасибо,
Кэмерон.


person Cameron    schedule 03.06.2009    source источник


Ответы (5)


Для записи:

JavaScript               |  Python
----------------------------------- 
encodeURI(str)           |  urllib.quote(str, safe='~@#$&()*!+=:;,.?/\'');
-----------------------------------
encodeURIComponent(str)  |  urllib.quote(str, safe='~()*!.\'')
person mjhm    schedule 08.07.2011
comment
Для еще более подвесной записи encodeURIComponent использует UTF-8, а urllib.quote(u'é'), например, выдает исключение. Эквивалентная кодировка Python должна быть urllib.quote(unicode(str).encode('utf-8'), safe=... - person Cameron; 07.06.2012
comment
В Python3 следует использовать urllib.parse.quote(s, safe='...'). кодировка по умолчанию utf-8. См. docs.python.org/3.0/library/< /а> - person Yo Hsiao; 26.07.2017

Хорошо, я думаю, что я собираюсь использовать гибридный пользовательский набор функций:

Кодирование: используйте encodeURIComponent(), затем верните косую черту.
Декодирование: декодируйте все найденные значения %hex.

Вот более полный вариант того, что я в итоге использовал (он также правильно обрабатывает Unicode):

function quoteUrl(url, safe) {
    if (typeof(safe) !== 'string') {
        safe = '/';    // Don't escape slashes by default
    }

    url = encodeURIComponent(url);

    // Unescape characters that were in the safe list
    toUnencode = [  ];
    for (var i = safe.length - 1; i >= 0; --i) {
        var encoded = encodeURIComponent(safe[i]);
        if (encoded !== safe.charAt(i)) {    // Ignore safe char if it wasn't escaped
            toUnencode.push(encoded);
        }
    }

    url = url.replace(new RegExp(toUnencode.join('|'), 'ig'), decodeURIComponent);

    return url;
}


var unquoteUrl = decodeURIComponent;    // Make alias to have symmetric function names

Обратите внимание: если вам не нужны «безопасные» символы при кодировании ('/' по умолчанию в Python), вы можете просто напрямую использовать встроенные функции encodeURIComponent() и decodeURIComponent().

Кроме того, если в строке есть символы Unicode (т.е. символы с кодовой точкой >= 128), то для обеспечения совместимости с encodeURIComponent() JavaScript, Python quote_url() должен быть:

def quote_url(url, safe):
    """URL-encodes a string (either str (i.e. ASCII) or unicode);
    uses de-facto UTF-8 encoding to handle Unicode codepoints in given string.
    """
    return urllib.quote(unicode(url).encode('utf-8'), safe)

И unquote_url() будет:

def unquote_url(url):
    """Decodes a URL that was encoded using quote_url.
    Returns a unicode instance.
    """
    return urllib.unquote(url).decode('utf-8')
person Cameron    schedule 03.06.2009
comment
Если вы собираетесь ответить на свой вопрос, по крайней мере, найдите время, чтобы составить более подробный ответ, чтобы помочь другим, которые наткнулись на тот же вопрос. - person Chris F; 04.04.2011
comment
@Chris: Хм, извини за это. Я расширю свой ответ и добавлю код. - person Cameron; 04.04.2011
comment
Я использовал функцию unquote_url , но столкнулся с проблемами при переходе на Python 3 — декодирование выполняется автоматически в Python 3, в Python 2 оно по-прежнему требуется. Я не мог придумать способ сделать это хорошо, чтобы он работал на обоих языках. Мой код py3 urllib.parse.unquote(six.text_type(a)) - person Charles L.; 11.06.2019

Библиотека requests немного более популярна, если вы не возражаете против дополнительной зависимости

from requests.utils import quote
quote(str)
person Milimetric    schedule 11.02.2016

Питон: urllib.quote

Javascript:unescape

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

Это появилось, когда я гуглил, поэтому я добавил это для всех остальных, если не конкретно для исходного вопроса.

person Community    schedule 01.06.2010

Попробуйте регулярное выражение. Что-то вроде этого:

mystring.replace(/[\xFF-\xFFFF]/g, "%" + "$&".charCodeAt(0));

Это заменит любой символ выше порядкового номера 255 соответствующим представлением %HEX.

person jiggy    schedule 03.06.2009
comment
Это отлично подходит для символов выше 255, но есть и другие забавные символы, которые перехватывает кавычка ниже 255 (например, '?', '&', '@' и другие, о которых я не знаю) - person Cameron; 06.06.2009
comment
Скобки обозначают набор символов, который может включать как отдельные символы, так и диапазоны. Вы можете так же легко написать его как /[\?&@\xFF-\xFFFF]/g для достижения такого результата. Вам просто нужно экранировать любые символы, которые также содержат специальные символы регулярного выражения (например, ? или /). - person jiggy; 08.06.2009