请求中的数据和参数有什么区别?

12
我将使用Python requests模块,以前我的参数发送方式如下:
requests.post(url=url, params=params)

但是今天,我发现我的数据发送方式失败了,我改成了这样:
requests.post(url=url, data=params)

那就好,dataparams有什么区别?

我注意到该请求收到了一个头部X-Requested-With:XMLHttpRequest,这是因为这个吗?


你确定你是在获取而不是发布吗? - Peter Wood
当你将它作为参数发送时,你收到了什么错误? - Ross Drew
罗杰,你真丢人。你可以轻松查看此线程的历史记录,我是第一个正确回答你问题的人,而@ZN13给出了错误的答案。然后,在我的回答之后,他编辑了他的答案并进行了更正,最终你将他的答案标记为正确答案。他的行为很可悲,但你通过这样的奖励来鼓励他。我很高兴这个社区中绝大多数的人不像你们这些人。 - thelawnmowerman
3个回答

18
根据requests文档
  • requests.post(url, data=data)将发出一个HTTP POST请求,
  • requests.get(url, params=params)将发出一个HTTP GET请求。

要了解两者之间的区别,请参阅此答案

以下是如何在GET中使用params:

payload = {'key1': 'value1', 'key2': 'value2'}
r = requests.get('http://httpbin.org/get', params=payload)
print(r.text)

哪个输出

{
  "args": {
    "key1": "value1", 
    "key2": "value2"
  }, 
  [...]
  "url": "http://httpbin.org/get?key1=value1&key2=value2"
}

请注意,有效载荷最终出现在URL的查询字符串中。由于它们出现在那里,任何有访问该URL权限的人都可以查看它们,这就是为什么不应将查询字符串用于密码等敏感数据的原因。
以下是POST方法中数据的使用方式:
payload = 'foobar'
r = requests.post('http://httpbin.org/post', data=payload)
print(r.text)

这将输出

{
  "args": {}, 
  "data": "foobar", 
  [...]
  "url": "http://httpbin.org/post"
}

请注意,POST数据不会显示在查询字符串中,因为它们是通过请求正文传输的。

对这个答案的批评指出了更多的选项。我在原始回答中从未否认过这样的事情,但让我们仔细看看。

文档示例总是显示:

  • 用于GET的params关键字,以及
  • 用于POST的data关键字

但这并不意味着它们是互斥的。

理论上,您可以在POST中混合使用两者:

data = 'foobar'
params = {'key1': 'value1', 'key2': 'value2'}
r = requests.post('http://httpbin.org/post', params=params, data=data)
print(r.text)

哪个输出

{
  "args": {
    "key1": "value1", 
    "key2": "value2"
  }, 
  "data": "foobar", 
  [...]
  "url": "http://httpbin.org/post?key1=value1&key2=value2"
}

但是您不能将数据混合到GET请求中:

data = 'foobar'
params = {'key1': 'value1', 'key2': 'value2'}
r = requests.get('http://httpbin.org/get', params=params, data=data)
print(r.text)

输出:

{
  "args": {
    "key1": "value1", 
    "key2": "value2"
  }, 
  [...]
  "url": "http://httpbin.org/get?key1=value1&key2=value2"
}

注意数据字段已经消失。

发布(post)方法不会在URL中发送数据,而获取(get)方法会。 - Sekar Ramu
@SekarRamu 看起来我写的代码示例是正确的,但是我在上面的文本中打错了字,所以我写成了 requests.post 而不是 requests.get。现在应该已经修复了。 - ZN13

6
首先,有两种不同的方法:
- `requests.post()` 发送 POST 请求(将所有参数放入消息体中) - `requests.get()` 发送 GET 请求(将所有参数放在 URL 中)
然后,根据文档,您可以选择两个参数来发送所有键/值数据:
- `params=`,无需字符串修改。 - `data=`,对参数应用表单编码字符串修改。
因此,您有4种选择发送请求:
- `requests.post(url, params=)` - `requests.post(url, data=)` - `requests.get(url, params=)` - `requests.get(url, data=)`
我认为目前接受的答案是不正确的。他实际上谈论的是`requests.post()`,但在自己的示例中使用了`requests.get()`。

错误。你不能在GET请求中使用data关键字。它会悄悄地将其删除。 - ZN13

1
参数被发送到URI中(附加到URI上)(http://www.answer.com/here?param1=1&param2=2),而数据被发送到请求正文中。通常,敏感数据或大量发送的数据会以POST方式发送到请求正文中,因为这样更容易保护并且不会导致巨大的URI。

为什么更容易保护安全? - Peter Wood
1
因为URI是以明文形式发送的,并且通常存储在服务器日志中,所以如果您发送类似安全令牌/用户名/密码之类的内容,任何人都可以看到(并使用)它。 - Ross Drew
数据仍然可能被嗅探。您可以使用 https:// 进行安全保护。编辑:不,您不能这样做 - Peter Wood
不,你不能。那只保护网络层攻击。 - Ross Drew
1
谢谢提供链接。那太可怕了,但也非常有帮助和信息丰富。 - Peter Wood
@ZN13 r = requests.post('http://httpbin.org/post', data=payload) 应该将负载放在 'forms' 而不是 'data' 下,除非您添加一个包含 content-type 的标头。 - blessedk

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接