我试图在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
)
我不知道问题出在哪里,也无法调试。谢谢!
发布于 2015-07-15 14:41:43
简而言之,您的问题是,在urlfetch
示例中,您将访问令牌嵌入到请求主体中,而且由于发出GET请求,-which无法携带任何请求体--这些信息将被丢弃。
为什么你的第一个片段能工作?
因为requests.get()
采用可选的params
参数,意思是:“使用我给您的字典,将它的所有键/值对转换为查询字符串,并将其附加到主URL中。”
因此,在窗帘的后面,requests.get()
正在构建这样的字符串:
https://api.particle.io/v1/devices?access_token=ACCESS_TOKEN
这是正确的端点,您应该指向GET请求。
为什么你的第二个片段不能工作?
这一次,urlfetch.fetch()
使用了与requests.get()
不同的语法(但仍然是等价的)。这里要注意的重要一点是,payload
参数并不意味着与您以前在requests.get()
中使用的params
参数相同。
urlfetch.fetch()
期望我们的查询字符串-if any-已经被urlencoded编码到URL中了(这就是为什么urllib.urlencode()
在这里起作用)。另一方面,payload
是当您发出POST、put或修补请求时应该将请求体放在那里的地方,但是Parle.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
头了,因为我们毕竟没有任何内容。因此,可以从这个示例调用中删除headers
参数。
作为进一步的参考,请看一看urlfetch.fetch()
参考文献和这根线,它们有望使您更深入地了解HTTP方法、参数和请求体,而不是我这里糟糕的解释。
PS:如果particle.io服务器支持它(它们应该支持它),那么您应该远离这个身份验证模式,而是将令牌放在Authorization: Bearer <access_token>
头中。在URL中携带访问令牌并不是一个好主意,因为这样可以更明显地看到它们,并且倾向于保持在服务器上,因此会带来安全风险。另一方面,在TLS会话中,所有请求标头都是加密的,因此您的auth令牌隐藏得很好。
发布于 2015-07-15 14:42:50
好的,因此,事实证明,不能包含使用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
)
这对我有用。
https://stackoverflow.com/questions/31441350
复制