POST 来自 Retrofit 的请求以意想不到的方式工作
POST request from Retrofit works in unexpected way
有一个使用 HTTPS 的 third-party 网站,其起始页在登录时执行 POST。我已经在我的浏览器中检查了 POST 请求,然后我已经能够使用 Fiddler 的作曲家手动创建请求。因此,根据凭据,我可以成功或不成功地登录 Fiddler。 return 代码始终为 302,它分别伴随重定向(header "Location")到用户管理页面或登录失败页面。
但是,当我使用 Retrofit 库创建该请求时,它不起作用。我收到响应代码 200,在这种特定情况下,这不被视为成功。
为了检查来自 Retrospect 的 POST 请求,我将其定向到 Fiddler (http://localhost:8888) 而不是 third-party URL。如果我将该请求复制到作曲家并将 URL 调整为 third-party 一个,该请求就会起作用。也就是说,我没有发现 Retrofit 构建的请求有任何问题。
有人知道哪里出了问题吗?
我的代码是用 Kotlin 写的,但如果你知道的话应该很容易理解 Java:
import okhttp3.ResponseBody
import retrofit2.Call
import retrofit2.Retrofit
import retrofit2.http.*
interface MyApi {
@POST("<relative login url>")
@FormUrlEncoded
@Headers(
//...
)
fun login(
@Field("username") username: String,
@Field("password") password: String
) : Call<ResponseBody>;
}
fun main(args: Array<String>) {
val baseUrl = "https://<url>"
val retrofit = Retrofit.Builder().baseUrl(baseUrl).build()
val myApi = retrofit.create(MyApi::class.java)
val code = myApi.login("<username>", "<password>").execute().code()
println(code)
}
如评论中所述,但为了让其他人也更容易理解,这里有一个答案。
当 retrofit
与 okhttp
一起使用时,默认情况下将遵循重定向。这是因为默认 okhttp
客户端设置为遵循重定向。这就是为什么你永远不会得到 302
- 重定向会自动跟随,你会从跟随的 url.
中得到 200
您可以通过使用正确配置的 okhttp 客户端构建改造实例来禁用此行为:
OkHttpClient client = new OkHttpClient.Builder()
.followRedirects(false)
.followSslRedirects(false)
.build();
Retrofit retrofit = new Retrofit.Builder()
.client(client)
// other configurations for retrofit
.build();
请注意,我们在这里创建了一个改造实例,客户端配置 not 以遵循重定向。这将有效地让您收到 302
和其他重定向代码。
(注意我这里没有完整配置retrofit实例,重点回答重要部分)
有一个使用 HTTPS 的 third-party 网站,其起始页在登录时执行 POST。我已经在我的浏览器中检查了 POST 请求,然后我已经能够使用 Fiddler 的作曲家手动创建请求。因此,根据凭据,我可以成功或不成功地登录 Fiddler。 return 代码始终为 302,它分别伴随重定向(header "Location")到用户管理页面或登录失败页面。
但是,当我使用 Retrofit 库创建该请求时,它不起作用。我收到响应代码 200,在这种特定情况下,这不被视为成功。
为了检查来自 Retrospect 的 POST 请求,我将其定向到 Fiddler (http://localhost:8888) 而不是 third-party URL。如果我将该请求复制到作曲家并将 URL 调整为 third-party 一个,该请求就会起作用。也就是说,我没有发现 Retrofit 构建的请求有任何问题。
有人知道哪里出了问题吗?
我的代码是用 Kotlin 写的,但如果你知道的话应该很容易理解 Java:
import okhttp3.ResponseBody
import retrofit2.Call
import retrofit2.Retrofit
import retrofit2.http.*
interface MyApi {
@POST("<relative login url>")
@FormUrlEncoded
@Headers(
//...
)
fun login(
@Field("username") username: String,
@Field("password") password: String
) : Call<ResponseBody>;
}
fun main(args: Array<String>) {
val baseUrl = "https://<url>"
val retrofit = Retrofit.Builder().baseUrl(baseUrl).build()
val myApi = retrofit.create(MyApi::class.java)
val code = myApi.login("<username>", "<password>").execute().code()
println(code)
}
如评论中所述,但为了让其他人也更容易理解,这里有一个答案。
当 retrofit
与 okhttp
一起使用时,默认情况下将遵循重定向。这是因为默认 okhttp
客户端设置为遵循重定向。这就是为什么你永远不会得到 302
- 重定向会自动跟随,你会从跟随的 url.
200
您可以通过使用正确配置的 okhttp 客户端构建改造实例来禁用此行为:
OkHttpClient client = new OkHttpClient.Builder()
.followRedirects(false)
.followSslRedirects(false)
.build();
Retrofit retrofit = new Retrofit.Builder()
.client(client)
// other configurations for retrofit
.build();
请注意,我们在这里创建了一个改造实例,客户端配置 not 以遵循重定向。这将有效地让您收到 302
和其他重定向代码。
(注意我这里没有完整配置retrofit实例,重点回答重要部分)