请求有效而 URLFetch 无效
Requests works and URLFetch doesn't
我正尝试在 google 应用引擎应用中向 python 中的粒子服务器发出请求。
在我的终端中,我可以简单而成功地完成请求,请求如下:
res = requests.get('https://api.particle.io/v1/devices', params={"access_token": {ACCESS_TOKEN}})
但在我的应用程序中,同样的事情不适用于 urlfetch,它一直告诉我找不到访问令牌:
url = 'https://api.particle.io/v1/devices'
payload = {"access_token": {ACCESS_TOKEN}}
form_data = urllib.urlencode(payload)
res = urlfetch.fetch(
url=url,
payload=form_data,
method=urlfetch.GET,
headers={
'Content-Type':
'application/x-www-form-urlencoded'
},
follow_redirects=False
)
我不知道是什么问题,也没有办法调试。谢谢!
简而言之,您的问题是,在您的 urlfetch
示例中,您将访问令牌嵌入到请求 body 中,并且由于您发出的是 GET 请求 - 无法携带与他们的任何请求 body - 此信息将被丢弃。
为什么您的第一个代码段有效?
因为 requests.get()
采用可选的 params
参数,这意味着:"take this dictionary I give you, convert all its key/value pairs into a query string and append it to the main URL"
所以,在幕后,requests.get()
正在构建这样一个字符串:
https://api.particle.io/v1/devices?access_token=ACCESS_TOKEN
这是您应该将 GET 请求指向的正确端点。
为什么你的第二个代码段不起作用?
这一次,urlfetch.fetch()
使用与 requests.get()
不同的语法(但仍然等效)。这里需要注意的重要一点是 payload
参数 与 requests.get()
之前使用的 params
参数的含义不同 。
urlfetch.fetch()
期望我们的查询字符串 - 如果有的话 - 已经被 urlencoded 到 URL (这就是 urllib.urlencode()
在这里发挥作用的原因)。另一方面,payload
是您应该放置请求 body 的地方,以防您发出 POST、PUT 或 PATCH 请求,但 particle.io 的端点不是期待您的 OAuth 访问令牌在那里。
这样的东西应该可以工作(免责声明:未测试):
auth = {"access_token": {ACCESS_TOKEN}}
url_params = urllib.urlencode(auth)
url = 'https://api.particle.io/v1/devices?%s' % url_params
res = urlfetch.fetch(
url=url,
method=urlfetch.GET,
follow_redirects=False
)
请注意,现在我们不再需要您之前的 Content-type
header,因为我们毕竟没有携带任何内容。因此,可以从此示例调用中删除 headers
参数。
如需进一步参考,请查看 urlfetch.fetch()
reference and this SO thread,与我在此处的拙劣解释相比,它有望让您更好地了解 HTTP 方法、参数和请求主体。
PS: 如果 particle.io 服务器支持(他们应该支持),您应该远离此身份验证模式并将您的令牌放在 Authorization: Bearer <access_token>
header 代替。在 URLs 中携带访问令牌不是一个好主意,因为这样它们更容易看到并且倾向于保持登录在服务器中,因此会带来安全风险。另一方面,在 TLS session 中,所有请求 header 总是被加密,因此您的身份验证令牌被很好地隐藏在那里。
好的,事实证明,不能使用 Urlfetch 为 GET 请求包含有效负载。相反,必须使用“?”将参数包含在 url 中。语法如下:
url = 'https://api.particle.io/v1/devices'
url = url + '?access_token=' + {ACCESS_TOKEN}
res = urlfetch.fetch(
url=url,
method=urlfetch.GET,
follow_redirects=False
)
这对我有用。
我正尝试在 google 应用引擎应用中向 python 中的粒子服务器发出请求。
在我的终端中,我可以简单而成功地完成请求,请求如下:
res = requests.get('https://api.particle.io/v1/devices', params={"access_token": {ACCESS_TOKEN}})
但在我的应用程序中,同样的事情不适用于 urlfetch,它一直告诉我找不到访问令牌:
url = 'https://api.particle.io/v1/devices'
payload = {"access_token": {ACCESS_TOKEN}}
form_data = urllib.urlencode(payload)
res = urlfetch.fetch(
url=url,
payload=form_data,
method=urlfetch.GET,
headers={
'Content-Type':
'application/x-www-form-urlencoded'
},
follow_redirects=False
)
我不知道是什么问题,也没有办法调试。谢谢!
简而言之,您的问题是,在您的 urlfetch
示例中,您将访问令牌嵌入到请求 body 中,并且由于您发出的是 GET 请求 - 无法携带与他们的任何请求 body - 此信息将被丢弃。
为什么您的第一个代码段有效?
因为 requests.get()
采用可选的 params
参数,这意味着:"take this dictionary I give you, convert all its key/value pairs into a query string and append it to the main URL"
所以,在幕后,requests.get()
正在构建这样一个字符串:
https://api.particle.io/v1/devices?access_token=ACCESS_TOKEN
这是您应该将 GET 请求指向的正确端点。
为什么你的第二个代码段不起作用?
这一次,urlfetch.fetch()
使用与 requests.get()
不同的语法(但仍然等效)。这里需要注意的重要一点是 payload
参数 与 requests.get()
之前使用的 params
参数的含义不同 。
urlfetch.fetch()
期望我们的查询字符串 - 如果有的话 - 已经被 urlencoded 到 URL (这就是 urllib.urlencode()
在这里发挥作用的原因)。另一方面,payload
是您应该放置请求 body 的地方,以防您发出 POST、PUT 或 PATCH 请求,但 particle.io 的端点不是期待您的 OAuth 访问令牌在那里。
这样的东西应该可以工作(免责声明:未测试):
auth = {"access_token": {ACCESS_TOKEN}}
url_params = urllib.urlencode(auth)
url = 'https://api.particle.io/v1/devices?%s' % url_params
res = urlfetch.fetch(
url=url,
method=urlfetch.GET,
follow_redirects=False
)
请注意,现在我们不再需要您之前的 Content-type
header,因为我们毕竟没有携带任何内容。因此,可以从此示例调用中删除 headers
参数。
如需进一步参考,请查看 urlfetch.fetch()
reference and this SO thread,与我在此处的拙劣解释相比,它有望让您更好地了解 HTTP 方法、参数和请求主体。
PS: 如果 particle.io 服务器支持(他们应该支持),您应该远离此身份验证模式并将您的令牌放在 Authorization: Bearer <access_token>
header 代替。在 URLs 中携带访问令牌不是一个好主意,因为这样它们更容易看到并且倾向于保持登录在服务器中,因此会带来安全风险。另一方面,在 TLS session 中,所有请求 header 总是被加密,因此您的身份验证令牌被很好地隐藏在那里。
好的,事实证明,不能使用 Urlfetch 为 GET 请求包含有效负载。相反,必须使用“?”将参数包含在 url 中。语法如下:
url = 'https://api.particle.io/v1/devices'
url = url + '?access_token=' + {ACCESS_TOKEN}
res = urlfetch.fetch(
url=url,
method=urlfetch.GET,
follow_redirects=False
)
这对我有用。