Выборка JavaScript кодирует эмоджи в отличие от запросов Python - PullRequest
0 голосов
/ 11 июля 2019

Я пытаюсь изменить свой SSID Wi-Fi на эмодзи, но веб-интерфейс этого не позволяет. Вместо этого я фиксирую действительный запрос PUT в API маршрутизатора, копирую его как fetch вызов, используя инструменты разработчика Chrome, меняю SSID на смайлик и повторяю запрос. Отлично работает.

Однако, когда я пытаюсь сделать это с помощью Python Requests, он экранирует эмодзи (?) в соответствующие экранированные символы JavaScript: \uD83E\uDD20. Когда это отправляется на маршрутизатор, оно каким-то образом переводится в > (знак «больше», за которым следует пробел). Это расстраивает, потому что я предполагаю, что оба метода будут кодировать эмодзи одинаково.

Так как он работает с JavaScript fetch, должно быть некоторое различие в кодировании сообщения или смайлика.

Fetch Call: (эмодзи просто отображается как эмодзи, даже при проверке запроса с помощью Dev Tools) (отредактировано для краткости)

fetch("https://192.168.1.1/api/wireless", {
    "credentials": "omit",
    "headers": {
        "accept": "application/json, text/plain, */*",
        "content-type": "application/json;charset=UTF-8",
        "x-xsrf-token": "[The token for this login session]"
    },
    "referrer": "https://192.168.1.1/",
    "referrerPolicy": "no-referrer-when-downgrade",
    "body": "{
        \"wifi\": [{
            \"boring key 1\": \"boring value\",
            \"boring key 2\": \"boring value\",
            \"ssid\": \"?\",
            \"boring key 3\": \"boring value\",
            \"boring key 4\": \"boring value\"
        }]
    }",
    "method": "PUT",
    "mode": "cors"
});

Запрос вызова: (отредактировано для краткости)

res = session.put('https://192.168.1.1/api/wireless', 
                   verify=False, 
                   json={
                       "wifi":[{
                           "boring key 1":"boring value",
                           "boring key 2":"boring value",
                           "ssid":"?",
                           "boring key 3":
                           "boring value",
                           "boring key 4":"boring value"
                       }]
                   })

Так в чем же разница в том, как они кодируются? И как я могу увидеть, что фактический вывод выборки? (Dev Tools просто показывает эмодзи, без escape-последовательностей.)

1 Ответ

1 голос
/ 11 июля 2019

Обработка JSON по умолчанию, выполняемая аргументом json в библиотеке requests, по существу будет иметь значение ensure_ascii, равное True, так что этот тип закодированной формы будет предоставлен.По сути, этот put вызов будет отправлен на сервер как:

PUT / HTTP/1.1
Host: 192.168.1.1
User-Agent: python-requests/2.21.0
Accept-Encoding: gzip, deflate
Accept: */*
Connection: keep-alive
Content-Length: 24
Content-Type: application/json

{"demo": "\ud83e\udd20"}

Это не то, что вы хотите.Чтобы сделать то, что вы хотите, вам придется вручную кодировать JSON и явно указывать заголовки, например:

requests.put(
    'https://192.168.1.1',
    data=json.dumps({"demo": "?"}, ensure_ascii=False).encode('utf8'),
    headers={'Content-Type': 'application/json'},
)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...