我正在尝试使用post
软件包在Flutter中发送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,但是该函数会因未处理的异常而停止。
答案 0 :(得分:2)
除非响应代码为303,否则Dart HTTP客户端将不会follow redirects进行POST。对于GET或HEAD,它将跟随302重定向。
您会看到是否可以停止服务器发送重定向(以响应(可能是)有效的登录请求),而是发送200。
或者您也可以尝试通过将表单字段编码为URL来将登录请求作为GET发送,例如:
http://xxxxxxx/accounts/login/?username=xxxx&password=yyyy&csrfmiddlewaretoken=zzzz
您将必须对参数中的任何特殊字符进行URL编码。大概您也想使用HTTPS。
最后,URL是否以/
结尾?可能值得尝试/accounts/login
。
答案 1 :(得分:2)
我遇到了类似的问题,我通过添加带有 "Accept":"application/json" 的标头解决了这个问题。此后它只会返回 json 数据,否则它会提示使用 html url 重定向。
答案 2 :(得分:1)
我这样解决了:
在请求中添加followRedirects: false
和validateStatus: (status) return status < 500;}
。
通过这种方式,您可以在302
和其他headers
中获取信息。
答案 3 :(得分:0)
对302的重定向是响应GET或HEAD请求而进行的,从不进行POST。有时,服务器发送302作为对POST的响应(在我的情况下)。在这种情况下,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
}
答案 4 :(得分:0)
在我的情况下,此问题已通过在post方法中发送带有标头的cookie来解决
问题是API是使用HTML登录页面而不是JSON数据响应我的。
,当您执行si / log-
时,您将在响应标题中找到cookie键。,状态错误代码为302