Flutterでpost
リクエストをDIO
パッケージで送信しようとしています。
これがリクエストです:
getSessionId() async {
var csrf = await getCsrftoken();
var dio = new Dio(new Options(
baseUrl: "http://xxxxxxx/accounts/login/",
connectTimeout: 5000,
receiveTimeout: 100000,
// 5s
headers: {
'Cookie': "csrftoken=" + csrf
},
contentType: ContentType.JSON,
// Transform the response data to a String encoded with UTF8.
// The default value is [ResponseType.JSON].
responseType: ResponseType.PLAIN
));
var response;
response = await dio.post("http://xxxxxxx/accounts/login/",
data: {
"username": "xxxxx",
"password": "xxxxx",
"csrfmiddlewaretoken" : csrf
},
options: new Options(
contentType: ContentType.parse("application/x-www-form-urlencoded")),
);
print("StatusCode: ");
print(response.statusCode);
print("Response cookie: "); //THESE ARE NOT PRINTED
print(response.headers);
}
リクエストの後、私は次のようになります:
E/flutter ( 4567): [ERROR:flutter/Shell/common/Shell.cc(181)] Dart Error: Unhandled exception:
E/flutter ( 4567): DioError [DioErrorType.RESPONSE]: Http status error [302]
E/flutter ( 4567): #0 getSessionId (file:///C:/get_order/lib/main.Dart:36:14)
E/flutter ( 4567): <asynchronous suspension>
このリクエストから、sessionid
Cookieを取得するだけで済みますが、関数は未処理の例外で停止します。
私はこのように解決しました:
_followRedirects: false
_およびvalidateStatus: (status) { return status < 500;}
をリクエストに追加します。このような:
_var response = await Dio().post("http://myurl",
options: Options(
followRedirects: false,
validateStatus: (status) { return status < 500; }
),
);
_
このようにして、_302
_ headers
などから取得できます。
応答コードが303でない限り、Dart HTTPクライアントはPOSTに対して リダイレクトに従う を行いません。GETまたはHEADの場合は302リダイレクトに従います。
(おそらく)有効なログイン要求に応答してリダイレクトを送信するサーバーを停止し、代わりに200を送信できるかどうかを確認できます。
または、フォームフィールドをURLにエンコードして、ログインリクエストをGETとして送信してみることもできます。次に例を示します。
http://xxxxxxx/accounts/login/?username=xxxx&password=yyyy&csrfmiddlewaretoken=zzzz
パラメータに特殊文字をURLエンコードする必要があります。おそらく、あなたもHTTPSを使いたくなるでしょう。
最後に、URLの末尾は/
ですか? /accounts/login
を試す価値があるかもしれません。
302のリダイレクトは、GETまたはHEADリクエストに応答して行われますが、POSTに対しては行われません。サーバーがPOSTに応答して302を送信する場合があります)この場合、Dioがキャッチできる例外をスローします。サーバーのステータスコードが302かどうか、または別のエラーかどうかを確認してください。
try{
await dio.post( _urlLogin,
data:{...},
options: Options(
contentType: ContentType.parse("application/x-www-form-urlencoded"),
)
);
}on DioError catch(error){
if(error.response.statusCode == 302){
// do your stuff here
}
私の場合、この問題はpostメソッドのヘッダー付きのcookieを送信することで解決されました
問題は、APIがJSONデータではなくHTMLログインページを使用して私に応答していたことです。
また、si/logを実行すると、応答ヘッダーにcookieキーが表示されます-
とステータスエラーコードは302でした