我正在尝试使用http-conduit创建一个到电子表格API的post请求。不幸的是,帖子请求不起作用,谷歌表单服务器也没有提供任何关于我在请求中做错了什么的反馈。
我正在使用https://developers.google.com/google-apps/spreadsheets/创建一个POST请求,将新行添加到我的电子表格中。
我写的代码是:
import Network.HTTP.Conduit
import Network.HTTP.Types (hAuthorization)
import Network.Google.OAuth2
import qualified Data.ByteString.Char8 as B8
import qualified Data.ByteString.Builder as B
import qualified Data.ByteString.Lazy as L
scopes = ["https://spreadsheets.google.com/feeds"]
createToken client = getAccessToken client scopes (Just "./key.txt")
authorize token request = request
{ requestHeaders = [(hAuthorization, B8.pack $ "Bearer " ++ token)] }
-- post::String -> OAuth2Client ->String -> IO Status
post url client postData = do
print "inside post request"
token <- createToken client
request <- parseUrl url
-- $ "<?xml version='1.0' encoding='utf-8'?>" ++
let pd = B.toLazyByteString $ B.string7 postData
let req = request{
method = "POST"
, requestHeaders = [("Content-Type", "application/atom+xml"),
("Content-Length",B8.pack $ show $ length postData)]
, requestBody = RequestBodyLBS pd
}
let postReq = authorize token postReq
res <- withManager $ httpLbs req
print res
return $ responseStatus res
现在,当我用正确的url和字符串数据调用post时
<entry xmlns="http://www.w3.org/2005/Atom"
xmlns:gsx="http://schemas.google.com/spreadsheets/2006/extended">
<gsx:name>Pork</gsx:name>
<gsx:category>meat</gsx:category>
<gsx:healthiness>questionable</gsx:healthiness>
<gsx:type>2</gsx:type>
</entry>
我得到的回复是:
Response {responseStatus = Status {statusCode = 200, statusMessage = "OK"}, responseVersion = HTTP/1.1, responseHeaders = [("Content- Type","application/binary"),("X-Robots-Tag","noindex, nofollow, nosnippet"),("P3P","CP="This is not a P3P policy! See https://support.google.com/accounts/answer/151657?hl=en for more info.""),("P3P","CP="This is not a P3P policy! See https://support.google.com/accounts/answer/151657?hl=en for more info.""),("Date","Tue, 08 Dec 2015 23:52:23 GMT"),("Expires","Tue, 08 Dec 2015 23:52:23 GMT"),("Cache-Control","private, max-age=0"),("X-Content-Type-Options","nosniff"),("X-Frame-Options","SAMEORIGIN"),("X-XSS-Protection","1; mode=block"),("Content-Length","0"),("Server","GSE"),("Set-Cookie","NID=74=CW9_VUnww09KLa-geN3Oxz2Zdh17ognD-Lw3rsXDRUkdOeaiOOKGM4ZBqPXPlp6yxvApu5yqttLjgpqesV1SP4qsza1ZW6ompUGznQqNmVcU2dmyzWebeY8D-NZUijLI;Domain=.google.com;Path=/;Expires=Wed, 08-Jun-2016 23:52:23 GMT;HttpOnly"),("Set-Cookie","NID=74=o-ILV0SQxX_i8EZDtP1jfCU5McNvdDc9FSuZ6FO8ZwQBrFuLg9oxiNtNAnxBKVubB0C4vL2n8LW5NBQMcmpXMvmaYcO0wZbRs4AxpQ96GFPfz5-y9KRZwJ86m8XIjK46;Domain=.google.com;Path=/;Expires=Wed, 08-Jun-2016 23:52:23 GMT;HttpOnly"),("Alternate-Protocol","443:quic,p=0"),("Alt-Svc","clear")], responseBody = "", responseCookieJar = CJ {expose = [Cookie {cookie_name = "NID", cookie_value = "74=o-ILV0SQxX_i8EZDtP1jfCU5McNvdDc9FSuZ6FO8ZwQBrFuLg9oxiNtNAnxBKVubB0C4vL2n8LW5NBQMcmpXMvmaYcO0wZbRs4AxpQ96GFPfz5-y9KRZwJ86m8XIjK46", cookie_expiry_time = 2016-06-08 23:52:23 UTC, cookie_domain = "google.com", cookie_path = "/", cookie_creation_time = 2015-12-08 23:52:25.6609874 UTC, cookie_last_access_time = 2015-12-08 23:52:25.6609874 UTC, cookie_persistent = True, cookie_host_only = False, cookie_secure_only = False, cookie_http_only = True}]}, responseClose' = ResponseClose}
但OAuth游乐场给了我:
HTTP/1.1 201 Created
Alternate-protocol: 443:quic,p=0
Content-length: 1048
X-xss-protection: 1; mode=block
X-robots-tag: noindex, nofollow, nosnippet
X-content-type-options: nosniff
Gdata-version: 1.0
Transfer-encoding: chunked
Set-cookie: NID=74=fuRYIEz3fRhSSdeqgNf9nCOi3IDTxo5I2FBkhv94fb5RqTRs-B5CXExV7ot9_vsDYryi8AvWJWoF1MXj-7syryXXzzfERwAskFQ5T1WA0Rzvi6xjIvsoLWRbvqbI08AF;Domain=.google.com;Path=/;Expires =Wed, 08-Jun-2016 23:25:55 GMT;HttpOnly, NID=74=nm8Q6cWmCmjvaoJgzXBMrg5w9QJzelMfloleHmIkjNw06jI-kMG8U2NyHdb0O3McHFHtCz4IbIAvfJtCD-EWxw25vmyGyGnBCgnsQqUw8GBc09oe7lyoSeXE7LjQQOKv;Domain=.google.com;Path=/;Expires=Wed, 08-Jun-2016 23:25:55 GMT;HttpOnly
Expires: Tue, 08 Dec 2015 23:25:55 GMT
Vary: Accept, X-GData-Authorization, GData-Version
Server: GSE
-content-encoding: gzip
Location: https://spreadsheets.google.com/feeds/list/1hIEq4AAauzI8INelQRIvgxBhmzX44qAB_1QQpFJQ2Xo/od6/private/full/cyevm/246h23pn1mc9h0
Cache-control: private, max-age=0, must-revalidate, no-transform
Date: Tue, 08 Dec 2015 23:25:55 GMT
P3p: CP="This is not a P3P policy! See https://support.google.com/accounts/answer/151657?hl=en for more info.", CP="This is not a P3P policy! See https://support.google.com/accounts/answer/151657?hl=en for more info."
Alt-svc: clear
Content-type: application/atom+xml; charset=UTF-8
X-frame-options: SAMEORIGIN
Content-location: https://spreadsheets.google.com/feeds/list/1hIEq4AAauzI8INelQRIvgxBhmzX44qAB_1QQpFJQ2Xo/od6/private/full/cyevm/246h23pn1mc9h0
<?xml version='1.0' encoding='UTF-8'?>
<entry xmlns='http://www.w3.org/2005/Atom' xmlns:gsx='http://schemas.google.com/spreadsheets/2006/extended'>
<id>https://spreadsheets.google.com/feeds/list/1hIEq4AAauzI8INelQRIvgxBhmzX44qAB_1QQpFJQ2Xo/od6/private/full/cyevm</id>
<updated>2015-12-06T01:22:19.799Z</updated>
<category scheme='http://schemas.google.com/spreadsheets/2006' term='http://schemas.google.com/spreadsheets/2006#list'/>
<title type='text'>Pork</title>
<content type='text'>category: meat, healthiness: questionable, type: 2</content>
<link rel='self' type='application/atom+xml' href='https://spreadsheets.google.com/feeds/list/1hIEq4AAauzI8INelQRIvgxBhmzX44qAB_1QQpFJQ2Xo/od6/private/full/cyevm'/>
<link rel='edit' type='application/atom+xml' href='https://spreadsheets.google.com/feeds/list/1hIEq4AAauzI8INelQRIvgxBhmzX44qAB_1QQpFJQ2Xo/od6/private/full/cyevm/246h23pn1mc9h0'/>
<gsx:name>Pork</gsx:name>
<gsx:category>meat</gsx:category>
<gsx:healthiness>questionable</gsx:healthiness>
<gsx:type>2</gsx:type>
</entry>
有人能告诉我出了什么问题吗?提前谢谢。
如果授权信息传递不正确,google表单API服务器会发回200。在我发现我的错误并正确地传递授权令牌后,它对我有效。奇怪的是,谷歌为什么会回复200 OK。