JavaScript提取对表情符号的编码与Python请求不同

时间:2019-07-11 03:29:53

标签: javascript python http unicode python-requests

我正在尝试将我的Wi-Fi SSID更改为表情符号,但Web UI不允许使用。相反,我捕获了到路由器API的有效PUT请求,使用Chrome的开发工具将其复制为fetch调用,将SSID更改为表情符号,然后重播请求。效果很好。

但是,当我尝试使用Python Requests进行操作时,它会将表情符号(?)转义为相应的JavaScript转义:\uD83E\uDD20。当此消息发送到路由器时,它将以某种方式转换为>(大于符号,后跟一个空格)。这令人沮丧,因为我假设这两种方法都会以相同的方式编码表情符号。

由于它可以与JavaScript的fetch配合使用,因此消息或表情符号的编码方式必须有所不同。

提取呼叫:(即使使用开发工具检查请求,表情符号也只是显示为表情符号)(为简洁起见进行了编辑)

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仅显示表情符号,没有转义序列。)

1 个答案:

答案 0 :(得分:1)

json库中requests参数完成的默认JSON处理实际上将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'},
)