【问题标题】:From URL params (as bytes) to JSON string从 URL 参数(作为字节)到 JSON 字符串
【发布时间】:2020-04-13 16:29:05
【问题描述】:

我使用它从 URL 参数(作为 HTTP 请求正文中的字节接收)转换为 JSON 字符串:

import urllib.parse, json

def params_asbytes_to_json(b):
    s = b.decode()  # bytes to str
    x = urllib.parse.parse_qsl(s)  # parse_qsl
    d = dict(x)  # convert to dict
    return json.dumps(d)  # convert to string with json 

print(params_asbytes_to_json(b'a=b&c=d'))  # {"a": "b", "c": "d"}

它可以工作,但由于它涉及许多编码/解码步骤,我怀疑它效率低下(如果我的服务器收到很多请求)。

从字节 a=b&c=d 到 JSON 字符串 {"a": "b", "c": "d"} 是否有更短/更快的时间?


PS:此数据是从 HTML <form> 发送的,如下所示:

<form action='/do' method='post'>
<input type='text' name='a' value='b'>
<input type='submit'>
</form>

对于其他页面,通过(Vanilla)Javascript:

var xhr = new XMLHttpRequest();
xhr.open("POST", "/do");
xhr.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
var fd = new FormData(document.querySelector('form'));
fd.append('dt', +new Date());
xhr.send(new URLSearchParams(fd).toString());

PS:我已经阅读了How to send a JSON object using html form data,但我需要我的网站运行即使禁用 Javascript,所以我不能 100% 依赖 XMLHttpRequest + JSON.serialize:它需要只需使用&lt;form&gt; 提交即可。据我所知,标准的 HTML 表单不能直接发布为 JSON,对吗?

【问题讨论】:

  • 我觉得很好。从一种编码转换到另一种编码是有代价的。
  • @tdelaney 你认为有没有办法让原来的&lt;form action='/do' method='post'&gt; 直接作为JSON 发送?它会好得多,对我的服务器来说也不会那么重。
  • 我不认为这对你的服务器来说是沉重的,与实现 Web 服务器的其他一切相比,但是.... 有一个 application/json 表单提案 w3.org/TR/html-json-forms。我不知道它是否被广泛采用。
  • @tdelaney 这看起来是个不错的提议,希望能得到支持!我用 caniuse.com 搜索但没有找到,我也在 Chrome 上进行了测试,截至 2020 年 4 月,它似乎不起作用。

标签: javascript python json xmlhttprequest urllib


【解决方案1】:

您可以使用urllib.parse.parse_qs() 而不是urllib.parse.parse_qsl() 来节省一步。它返回字典而不是列表,因此您不需要 dict() 步骤。

但是,正如 cmets 中所指出的,这会将字典值设置为列表,而不是单个字符串,以允许查询字符串中的重复键。您的版本只是丢弃了重复项。所以要么按照你的方式去做,要么在调用json.dumps()之前从字典中的列表中提取元素。

您也不需要使用b.decode()urllib.parse 函数接受 bytes 对象并将其解码。

【讨论】:

  • IIRC, parse_qs 会给出 {'a': ['b']} 而不是 {'a': 'b'}。
  • @Basj - 好点。 parse_qs 通过列出一个参数来说明多个值。首先,这可能对 OP 更好,恕我直言。
  • 跳过解码的问题是dict会是bytes,json会报错。
  • 也许它应该是b.decode("ascii"),而不是仅仅解码为你的本地默认值。
猜你喜欢
  • 1970-01-01
  • 2014-11-29
  • 1970-01-01
  • 2011-04-30
  • 2012-10-13
  • 1970-01-01
  • 2020-11-28
  • 1970-01-01
  • 2014-04-07
相关资源
最近更新 更多