这个周末我正在学习使用 wreq,但我遇到了一些奇怪的行为。
我有一个模块AuthRequest
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE DeriveGeneric #-}
module AuthRequest where
import Data.Aeson
import GHC.Generics
import Data.Monoid
data AuthRequest = AuthRequest {
client_id :: String
, client_secret :: String
, grant_type :: String
} deriving (Generic, Show)
instance ToJSON AuthRequest where
toJSON (AuthRequest id_ secret grant) =
object [ "client_id" .= id_
, "client_secret" .= secret
, "grant_type" .= grant
]
toEncoding(AuthRequest id_ secret grant) =
pairs ("client_id" .= id_ <> "client_secret" .= secret <> "grant_type" .= grant)
和一个模块HttpDemo
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE DeriveGeneric #-}
module HttpDemo where
import Control.Lens
import Network.Wreq
import AuthRequest
import Data.Aeson
clientId = "some_id"
clientSecret = "some_secret"
url = "http://localhost:5000"
opts :: Options
opts = defaults
& header "Content-Type" .~ ["application/x-www-form-urlencoded"]
req :: AuthRequest
req = AuthRequest clientId clientSecret "credentials"
postIt = postWith opts url (toJSON req)
另一方面,我有一个简单的 python 烧瓶服务器,它通过断点侦听这个请求,这样我就可以看到通过的值。
当我查看request.form
服务器端时,我看到:ImmutableMultiDict([('{"client_secret":"some_secret","client_id":"some_id","grant_type":"whatever"}', '')])
关键是我的帖子正文应该是什么!
但是,如果我使用 requests python 库发出类似的请求
requests.post('http://localhost:5000', data={'client_id': clientId, 'client_secret': clientSecret, 'grant_type': grant_type}, headers={'content-type': 'application/x-www-form-urlencoded'})
我看到了我的期望:ImmutableMultiDict([('grant_type', 'whatever'), ('client_id', 'some_id'), ('client_secret', 'some_secret')])
我想我想要的是将此请求发送为x-www-form-urlencoded
. 我看到这里有一些文档,但不清楚如何进行。也许我需要一个 FormValue 实例?一个例子会很有帮助。