Android 上的 React Native 和 okhttp - 设置用户代理
React Native & okhttp on Android - Set User-Agent
我正在尝试在 Android 上使用 React Native 设置 User-Agent
。做了一些研究,看起来我应该使用 okhttp
Interceptor。我找到的一个示例解释了应该如何完成(Link),但我不确定如何注册拦截器。
所以为了设置 User-Agent
我正在使用这个 class:
public class CustomInterceptor implements Interceptor {
@Override public Response intercept(Interceptor.Chain chain) throws IOException {
Request originalRequest = chain.request();
Request requestWithUserAgent = originalRequest.newBuilder()
.removeHeader("User-Agent")
.header("User-Agent", "Trevor")
.build();
return chain.proceed(requestWithUserAgent);
}
}
那剩下的就是注册上面的拦截器了,应该在哪里注册呢?也许在 MainActivity.java
?
OkHttpClient okHttp = new OkHttpClient();
okHttp.interceptors().add(new CustomInterceptor());
我在构建应用程序时没有遇到任何错误,所以我认为 CustomInterceptor
应该没问题 - 只需要让应用程序使用它即可。
更新:
我目前正在尝试在 MainActivity
中注册拦截器,但它不会接收它:
public class MainActivity extends ReactActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
OkHttpClient client = new OkHttpClient();
client.networkInterceptors().add(new CustomInterceptor());
};
};
我已经使用 OkHttp 实现了此功能,我的代码与您的代码非常相似 - 一切正常。
考虑使用 addHeader("User-Agent", "Trevor")
而不是 header("User-Agent", "Trevor")
,因为后者将替换所有已设置的 headers。
我正在使用 okHttp.networkInterceptors().add(new CustomInterceptor());
而不是 okHttp.interceptors().add(new CustomInterceptor());
,但我认为这不是一个值得关注的问题。
Update 我也是用 onCreate()
方法做的。一切正常。
所以我终于弄明白了。这是用 React Native 覆盖 okhttp3
的 User-Agent 的解决方案。
创建名为 CustomInterceptor.java
的文件:
package com.trevor;
import okhttp3.Interceptor;
import okhttp3.Request;
import okhttp3.Response;
import java.io.IOException;
public class CustomInterceptor implements Interceptor {
public CustomInterceptor() {}
@Override
public Response intercept(Interceptor.Chain chain) throws IOException {
Request originalRequest = chain.request();
Request requestWithUserAgent = originalRequest.newBuilder()
.removeHeader("User-Agent")
.addHeader("User-Agent", "Trevor")
.build();
return chain.proceed(requestWithUserAgent);
}
}
然后在 MainActivity.java
override onCreate
方法中:
...
import com.facebook.react.modules.network.OkHttpClientProvider;
...
public class MainActivity extends ReactActivity {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
attachInterceptor();
}
private void attachInterceptor() {
OkHttpClient client = OkHttpClientProvider.getOkHttpClient();
client.networkInterceptors().add(new CustomInterceptor());
}
}
请注意,我正在导入 com.facebook.react.modules.network.OkHttpClientProvider;
并覆盖该客户端,而不是创建一个 vanilla OkHttpClient
,因为这是 React Native 将使用的客户端。
React Native 迭代如此之快以至于接受的答案对我不起作用。
对于 RN 0.27.2,我必须在我的 CustomInterceptor 中导入 okhttp3.OkHttpClient 并更改 MainActivity 中的 attachInterceptor() 方法以替换客户端。
private void attachInterceptor() {
OkHttpClient currentClient = OkHttpClientProvider.getOkHttpClient();
OkHttpClient replacementClient = currentClient.newBuilder().addNetworkInterceptor(new CustomInterceptor()).build();
OkHttpClientProvider.replaceOkHttpClient(replacementClient);
}
ekonstantinidis 的回答中的其他所有内容都对我有用。
老问题,但我们仍然 运行 遇到与 React Native 0.59 相同的问题。这是我们所做的修复(在 Kotlin 中),因为当尝试向已初始化的客户端添加拦截器时,最新版本的 okhttp 会阻止(并抛出异常):
import android.os.Build
import com.facebook.react.modules.network.OkHttpClientFactory
import com.jaredrummler.android.device.DeviceName
import okhttp3.Interceptor
import okhttp3.OkHttpClient
import okhttp3.Response
class UserAgentInterceptor(val userAgent: String): Interceptor {
override fun intercept(chain: Interceptor.Chain): Response {
val originalRequest = chain.request()
val correctRequest = originalRequest.newBuilder()
.removeHeader("User-Agent")
.addHeader("User-Agent", userAgent)
.build()
return chain.proceed(correctRequest)
}
}
class UserAgentClientFactory(val appName: String, val appVersion: String, val buildNumber: String): OkHttpClientFactory {
private fun userAgentValue(): String {
val deviceName = DeviceName.getDeviceName()
val osVersion = Build.VERSION.RELEASE
return "$appName/$appVersion (build: $buildNumber; device: $deviceName; OS: Android $osVersion)"
}
override fun createNewNetworkModuleClient(): OkHttpClient {
val builder = com.facebook.react.modules.network.OkHttpClientProvider.createClientBuilder()
return builder.addInterceptor(UserAgentInterceptor(userAgent = userAgentValue())).build()
}
}
这是在两个应用程序之间的共享库中完成的,因此我们传入了应用程序名称、版本和内部版本号。
应用程序本身的用法如下:
private fun configureUserAgent() {
val versionName = BuildConfig.VERSION_NAME
val versionCode = BuildConfig.VERSION_CODE
OkHttpClientProvider.setOkHttpClientFactory(UserAgentClientFactory(appName = "My App", appVersion = versionName, buildNumber = "$versionCode"))
}
这是从应用 activity 主程序中的 onCreate
方法调用的。
希望对您有所帮助!
None 这里的答案对我适用于 RN 0.63.2。我能够让它工作,并且在我的研究中能够找到(尽管非常稀少)支持此功能的文档。
我能找到的唯一文档是 this PR where someone added support for this feature (and broke the currently accepted answer). When I tried adding the interceptor as documented in the PR I got an exception related to CookieJar
which I was able to find a solution to in this (unresolved ) issue。
TLDR:
在名为 UserAgentInterceptor.java
的 MainApplication
所在的同一文件夹中添加一个 Java class 并将其放入其中:
package YOUR.PACKAGE.NAME; // <-- REPLACE ME
import okhttp3.Interceptor;
import okhttp3.Request;
import okhttp3.Response;
import java.io.IOException;
public class UserAgentInterceptor implements Interceptor {
public UserAgentInterceptor() {}
@Override
public Response intercept(Interceptor.Chain chain) throws IOException {
Request originalRequest = chain.request();
Request requestWithUserAgent = originalRequest.newBuilder()
.removeHeader("User-Agent")
.addHeader("User-Agent", "YOUR USER AGENT") // <-- REPLACE ME
.build();
return chain.proceed(requestWithUserAgent);
}
}
然后在名为 UserAgentClientFactory.java
的同一文件夹中创建另一个 Java class 并将其放入其中:
package YOUR.PACKAGE.NAME; // <-- REPLACE ME
import com.facebook.react.modules.network.OkHttpClientFactory;
import com.facebook.react.modules.network.ReactCookieJarContainer;
import okhttp3.OkHttpClient;
public class UserAgentClientFactory implements OkHttpClientFactory {
public OkHttpClient createNewNetworkModuleClient() {
return new OkHttpClient.Builder()
.cookieJar(new ReactCookieJarContainer())
.addInterceptor(new UserAgentInterceptor())
.build();
}
}
然后在您的 MainApplication
onCreate
方法中像这样注册工厂:
...
import com.facebook.react.modules.network.OkHttpClientProvider;
...
@Override
public void onCreate() {
super.onCreate();
OkHttpClientProvider.setOkHttpClientFactory(new UserAgentClientFactory());
// Your other code stuffs
}
就是这样!
我正在尝试在 Android 上使用 React Native 设置 User-Agent
。做了一些研究,看起来我应该使用 okhttp
Interceptor。我找到的一个示例解释了应该如何完成(Link),但我不确定如何注册拦截器。
所以为了设置 User-Agent
我正在使用这个 class:
public class CustomInterceptor implements Interceptor {
@Override public Response intercept(Interceptor.Chain chain) throws IOException {
Request originalRequest = chain.request();
Request requestWithUserAgent = originalRequest.newBuilder()
.removeHeader("User-Agent")
.header("User-Agent", "Trevor")
.build();
return chain.proceed(requestWithUserAgent);
}
}
那剩下的就是注册上面的拦截器了,应该在哪里注册呢?也许在 MainActivity.java
?
OkHttpClient okHttp = new OkHttpClient();
okHttp.interceptors().add(new CustomInterceptor());
我在构建应用程序时没有遇到任何错误,所以我认为 CustomInterceptor
应该没问题 - 只需要让应用程序使用它即可。
更新:
我目前正在尝试在 MainActivity
中注册拦截器,但它不会接收它:
public class MainActivity extends ReactActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
OkHttpClient client = new OkHttpClient();
client.networkInterceptors().add(new CustomInterceptor());
};
};
我已经使用 OkHttp 实现了此功能,我的代码与您的代码非常相似 - 一切正常。
考虑使用 addHeader("User-Agent", "Trevor")
而不是 header("User-Agent", "Trevor")
,因为后者将替换所有已设置的 headers。
我正在使用 okHttp.networkInterceptors().add(new CustomInterceptor());
而不是 okHttp.interceptors().add(new CustomInterceptor());
,但我认为这不是一个值得关注的问题。
Update 我也是用 onCreate()
方法做的。一切正常。
所以我终于弄明白了。这是用 React Native 覆盖 okhttp3
的 User-Agent 的解决方案。
创建名为 CustomInterceptor.java
的文件:
package com.trevor;
import okhttp3.Interceptor;
import okhttp3.Request;
import okhttp3.Response;
import java.io.IOException;
public class CustomInterceptor implements Interceptor {
public CustomInterceptor() {}
@Override
public Response intercept(Interceptor.Chain chain) throws IOException {
Request originalRequest = chain.request();
Request requestWithUserAgent = originalRequest.newBuilder()
.removeHeader("User-Agent")
.addHeader("User-Agent", "Trevor")
.build();
return chain.proceed(requestWithUserAgent);
}
}
然后在 MainActivity.java
override onCreate
方法中:
...
import com.facebook.react.modules.network.OkHttpClientProvider;
...
public class MainActivity extends ReactActivity {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
attachInterceptor();
}
private void attachInterceptor() {
OkHttpClient client = OkHttpClientProvider.getOkHttpClient();
client.networkInterceptors().add(new CustomInterceptor());
}
}
请注意,我正在导入 com.facebook.react.modules.network.OkHttpClientProvider;
并覆盖该客户端,而不是创建一个 vanilla OkHttpClient
,因为这是 React Native 将使用的客户端。
React Native 迭代如此之快以至于接受的答案对我不起作用。
对于 RN 0.27.2,我必须在我的 CustomInterceptor 中导入 okhttp3.OkHttpClient 并更改 MainActivity 中的 attachInterceptor() 方法以替换客户端。
private void attachInterceptor() {
OkHttpClient currentClient = OkHttpClientProvider.getOkHttpClient();
OkHttpClient replacementClient = currentClient.newBuilder().addNetworkInterceptor(new CustomInterceptor()).build();
OkHttpClientProvider.replaceOkHttpClient(replacementClient);
}
ekonstantinidis 的回答中的其他所有内容都对我有用。
老问题,但我们仍然 运行 遇到与 React Native 0.59 相同的问题。这是我们所做的修复(在 Kotlin 中),因为当尝试向已初始化的客户端添加拦截器时,最新版本的 okhttp 会阻止(并抛出异常):
import android.os.Build
import com.facebook.react.modules.network.OkHttpClientFactory
import com.jaredrummler.android.device.DeviceName
import okhttp3.Interceptor
import okhttp3.OkHttpClient
import okhttp3.Response
class UserAgentInterceptor(val userAgent: String): Interceptor {
override fun intercept(chain: Interceptor.Chain): Response {
val originalRequest = chain.request()
val correctRequest = originalRequest.newBuilder()
.removeHeader("User-Agent")
.addHeader("User-Agent", userAgent)
.build()
return chain.proceed(correctRequest)
}
}
class UserAgentClientFactory(val appName: String, val appVersion: String, val buildNumber: String): OkHttpClientFactory {
private fun userAgentValue(): String {
val deviceName = DeviceName.getDeviceName()
val osVersion = Build.VERSION.RELEASE
return "$appName/$appVersion (build: $buildNumber; device: $deviceName; OS: Android $osVersion)"
}
override fun createNewNetworkModuleClient(): OkHttpClient {
val builder = com.facebook.react.modules.network.OkHttpClientProvider.createClientBuilder()
return builder.addInterceptor(UserAgentInterceptor(userAgent = userAgentValue())).build()
}
}
这是在两个应用程序之间的共享库中完成的,因此我们传入了应用程序名称、版本和内部版本号。
应用程序本身的用法如下:
private fun configureUserAgent() {
val versionName = BuildConfig.VERSION_NAME
val versionCode = BuildConfig.VERSION_CODE
OkHttpClientProvider.setOkHttpClientFactory(UserAgentClientFactory(appName = "My App", appVersion = versionName, buildNumber = "$versionCode"))
}
这是从应用 activity 主程序中的 onCreate
方法调用的。
希望对您有所帮助!
None 这里的答案对我适用于 RN 0.63.2。我能够让它工作,并且在我的研究中能够找到(尽管非常稀少)支持此功能的文档。
我能找到的唯一文档是 this PR where someone added support for this feature (and broke the currently accepted answer). When I tried adding the interceptor as documented in the PR I got an exception related to CookieJar
which I was able to find a solution to in this (unresolved ) issue。
TLDR:
在名为 UserAgentInterceptor.java
的 MainApplication
所在的同一文件夹中添加一个 Java class 并将其放入其中:
package YOUR.PACKAGE.NAME; // <-- REPLACE ME
import okhttp3.Interceptor;
import okhttp3.Request;
import okhttp3.Response;
import java.io.IOException;
public class UserAgentInterceptor implements Interceptor {
public UserAgentInterceptor() {}
@Override
public Response intercept(Interceptor.Chain chain) throws IOException {
Request originalRequest = chain.request();
Request requestWithUserAgent = originalRequest.newBuilder()
.removeHeader("User-Agent")
.addHeader("User-Agent", "YOUR USER AGENT") // <-- REPLACE ME
.build();
return chain.proceed(requestWithUserAgent);
}
}
然后在名为 UserAgentClientFactory.java
的同一文件夹中创建另一个 Java class 并将其放入其中:
package YOUR.PACKAGE.NAME; // <-- REPLACE ME
import com.facebook.react.modules.network.OkHttpClientFactory;
import com.facebook.react.modules.network.ReactCookieJarContainer;
import okhttp3.OkHttpClient;
public class UserAgentClientFactory implements OkHttpClientFactory {
public OkHttpClient createNewNetworkModuleClient() {
return new OkHttpClient.Builder()
.cookieJar(new ReactCookieJarContainer())
.addInterceptor(new UserAgentInterceptor())
.build();
}
}
然后在您的 MainApplication
onCreate
方法中像这样注册工厂:
...
import com.facebook.react.modules.network.OkHttpClientProvider;
...
@Override
public void onCreate() {
super.onCreate();
OkHttpClientProvider.setOkHttpClientFactory(new UserAgentClientFactory());
// Your other code stuffs
}
就是这样!