Flutter - 在 POST 请求中处理状态代码 302
Flutter - Handle status code 302 in POST request
我正在尝试使用 DIO
包在 Flutter 中发送 post
请求。
请求如下:
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,但该函数因未处理的异常而停止。
除非响应代码为 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
.
我是这样解决的:
在请求中添加 followRedirects: false
和 validateStatus: (status) { return status < 500;}
。像这样:
var response = await Dio().post("http://myurl",
data: requestBody,
options: Options(
followRedirects: false,
validateStatus: (status) { return status < 500; }
),
);
这样你就可以从302
每headers
等得到。
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
}
在我的例子中,通过在 post 方法
中发送带有 header 的 cookie 解决了这个问题
问题是 API 是用 HTML 登录页面而不是 JSON 数据对我的回应。
当您在
中执行 si/log 时,您将在响应 header 中找到 cookie 密钥
状态错误代码为 302
我遇到了类似的问题,我通过添加 header 和 "Accept":"application/json" 解决了这个问题。从今以后它只会 return json 数据否则它会提示重定向 html url.
我正在尝试将其用于 webscraping...别问我为什么,哈哈。我来自 python/golang 并且我已经尝试过 http 包,但是我建议你使用 dio 包。
对于 dio,我正在执行以下操作:
Scrapers.client = Dio();
// create a local cookie to handle with sites that force you to use it
var cookieJar = CookieJar();
// assign middlewares to be "session like"
Scrapers.client?.interceptors.add(CookieManager(cookieJar));
// assign a logging middleware
Scrapers.client?.interceptors.add(LogInterceptor(responseBody: false));
// set the default content type to this client
Scrapers.client?.options.contentType = Headers.formUrlEncodedContentType;
...
static Future<Response> handleRedirects(Response r, int statusCode) async {
var redirects = 0;
while (r.statusCode == statusCode) {
print("redirect #${redirects++}");
final redirecturl = r.headers['location']![0];
r = await Scrapers.client!.post(redirecturl,
options: Options(
followRedirects: false,
validateStatus: (status) {
return status! < 500;
}));
}
return r;
}
...
Response r = await Scrapers.client!.post(url,
data: payload,
options: Options(
followRedirects: false,
validateStatus: (status) {
return status! < 500;
}));
r = await Scrapers.handleRedirects(r, 302);
注意这只是一个简单的方法。您可以根据需要更改它。
我正在尝试使用 DIO
包在 Flutter 中发送 post
请求。
请求如下:
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,但该函数因未处理的异常而停止。
除非响应代码为 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
.
我是这样解决的:
在请求中添加 followRedirects: false
和 validateStatus: (status) { return status < 500;}
。像这样:
var response = await Dio().post("http://myurl",
data: requestBody,
options: Options(
followRedirects: false,
validateStatus: (status) { return status < 500; }
),
);
这样你就可以从302
每headers
等得到。
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
}
在我的例子中,通过在 post 方法
中发送带有 header 的 cookie 解决了这个问题问题是 API 是用 HTML 登录页面而不是 JSON 数据对我的回应。
当您在
中执行 si/log 时,您将在响应 header 中找到 cookie 密钥状态错误代码为 302
我遇到了类似的问题,我通过添加 header 和 "Accept":"application/json" 解决了这个问题。从今以后它只会 return json 数据否则它会提示重定向 html url.
我正在尝试将其用于 webscraping...别问我为什么,哈哈。我来自 python/golang 并且我已经尝试过 http 包,但是我建议你使用 dio 包。
对于 dio,我正在执行以下操作:
Scrapers.client = Dio();
// create a local cookie to handle with sites that force you to use it
var cookieJar = CookieJar();
// assign middlewares to be "session like"
Scrapers.client?.interceptors.add(CookieManager(cookieJar));
// assign a logging middleware
Scrapers.client?.interceptors.add(LogInterceptor(responseBody: false));
// set the default content type to this client
Scrapers.client?.options.contentType = Headers.formUrlEncodedContentType;
...
static Future<Response> handleRedirects(Response r, int statusCode) async {
var redirects = 0;
while (r.statusCode == statusCode) {
print("redirect #${redirects++}");
final redirecturl = r.headers['location']![0];
r = await Scrapers.client!.post(redirecturl,
options: Options(
followRedirects: false,
validateStatus: (status) {
return status! < 500;
}));
}
return r;
}
...
Response r = await Scrapers.client!.post(url,
data: payload,
options: Options(
followRedirects: false,
validateStatus: (status) {
return status! < 500;
}));
r = await Scrapers.handleRedirects(r, 302);
注意这只是一个简单的方法。您可以根据需要更改它。