2017-05-13 4 views
0

이번 주말에 wreq를 사용하는 방법을 배우고 있는데 이상한 행동이있었습니다.wreq를 사용하여 x-www-form-urlencoded의 콘텐츠 유형으로 요청 보내기

I는 모듈 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) 

을 가지고, 내가 수 있도록 중단하여이 요청을 수신하는 간단한 파이썬 플라스크 서버가 오는 가치를보십시오. ImmutableMultiDict([('{"client_secret":"some_secret","client_id":"some_id","grant_type":"whatever"}', '')])

의 핵심은 내 게시물 본문해야합니다 것입니다 : 나는 서버 측에 request.form 볼 때

는,이보세요! 내가 요청 파이썬 라이브러리

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로 요청을 보내는 것입니다 내가 생각 내가 원하는

. 이 문서 주위에 here 문서가 있지만 처리 방법이 명확하지 않습니다. 어쩌면 FormValue 인스턴스가 필요할까요? 예가 도움이 될 것입니다.

+0

다음과 같이 상수의 유형을 제공했다'응용 프로그램/x-www-form-urlencoded'로 완전히 다른 인코딩입니다. –

+0

@AlexisKing 궁극적으로이 요청을 대상으로하는 응용 프로그램은 urlencoded 형식을 기대합니다. 그래서 내가 물어야하는 것은 어쩌면 파이썬 요청이 보내는 것과 일치하도록 url로 인코딩 된 데이터를 보내는 것인가? – munk

+1

예, 올바른 질문과 같습니다. 서버가 양식 데이터를 예상하는 경우 JSON 전송은 작동하지 않습니다. –

답변

1

@Alexis와의 토론에 따르면 클라이언트가 JSON을 보내는 것처럼 보이지만 서버는 urlencoded가 예상됩니다. Post의 설명서는 := 생성자를 사용하여 urlencoded 데이터를 보내는 방법을 보여줍니다. 이 경우이 나는 기본이 application/x-www-form-urlencoded을 사용하는 것으로 보인다 이후 post보다는 postWith를 사용하여 예를 준

postIt = post url ["client_id" := clientId, "client_secret" := clientSecret, "grant_type" := grantType] 

될 것이다.


OverloadedStrings과 약간의 복잡성이있는 것으로 보입니다. 컴파일 가능한 프로그램을 만들려면, 당신의 콘텐츠 형식이 응용 프로그램/json`이 아니라 '해야한다는 AuthRequest 모듈을 제거하고 JSON을 보내는 경우 명시 적으로

{-# LANGUAGE OverloadedStrings #-} 
module Main where 

import Network.Wreq 
import Data.ByteString as B 

clientId = "some_id" :: ByteString 
clientSecret = "some_secret" :: ByteString 
grantType = "credentials" :: ByteString 
url = "http://localhost:8080" 

postIt = post url ["client_id" := clientId, "client_secret" := clientSecret, "grant_type" := grantType] 

main = postIt