List icon 目录

网络

本指南展示了如何使用与网络相关的功能,例如代理、网络事件、身份验证、TLS、客户端证书身份验证等。

可以通过以下方式获取 Network 实例来访问与网络相关的功能:

Java
Kotlin

var network = profile.network();

val network = profile.network()

Accept-Language 标头

JxBrowser 允许通过 Network.acceptLanguage(String) 方法配置 Accept-Language HTTP 标头值。

例如,“fr, en-gb;q=0.8, en;q=0.7” 值表示:“我更喜欢法语, 但也会接受英式英语, 以及其他类型的英语”:

Java
Kotlin

network.acceptLanguage("fr, en-gb;q=0.8, en;q=0.7");

network.acceptLanguage("fr, en-gb;q=0.8, en;q=0.7")

服务器白名单

HTTP 服务器授权白名单

您可以配置 HTTP 服务器授权白名单,该白名单表示一个包含以逗号/分号分隔的 URL 列表的字符串。例如:

Java
Kotlin

network.httpAuthPreferences().serverWhitelist("*google.com,*example.com,*baz");

network.httpAuthPreferences()
    .serverWhitelist("*google.com,*example.com,*baz")

HTTP 网络代理白名单

要配置 HTTP 网络代理白名单,您可以使用以下描述的方法:

Java
Kotlin

network.httpAuthPreferences().delegateWhitelist("*google.com,*example.com,*baz");

network.httpAuthPreferences()
    .delegateWhitelist("*google.com,*example.com,*baz")

TLS(传输层安全性协议)

证书验证

默认情况下,Chromium 在加载网页期间会验证从 Web 服务器获取的所有 SSL 证书。JxBrowser 允许修改此默认行为,并控制验证过程。

要处理证书验证,请使用 VerifyCertificateCallback 回调。在调用此回调之前,Chromium 会验证 SSL 证书并将验证结果提供给回调。回调会接收验证结果和 SSL 证书本身。您可以验证给定的 SSL 证书并将验证结果通知 Engine。

例如:

Java
Kotlin

network.set(VerifyCertificateCallback.class, (params) -> {
    // 要验证的 SSL 证书。
    var certificate = params.certificate();
    // 默认验证器执行的验证结果。
    var verificationErrors = params.verificationErrors();
    // 应使用默认验证结果。
    return VerifyCertificateCallback.Response.defaultAction();
});

network.register(VerifyCertificateCallback { params ->
    // 要验证的 SSL 证书。
    val certificate = params.certificate()
    // 默认验证器执行的验证结果。
    val verificationErrors = params.verificationErrors()
    // 应使用默认验证结果。
    VerifyCertificateCallback.Response.defaultAction()
})

客户端证书认证

JxBrowser 支持使用 HTTPS 客户端证书进行认证。请查看身份验证指南以获取详细信息。

方案

该库提供了一个 API,允许注册自定义方案并拦截使用标准方案(如 HTTP 或 HTTPS)的 URL 请求。

在这两种情况下,具有相应方案的 URL 请求将被拦截,并提供响应数据,就好像这些数据是从 Web 服务器发送的一样。使用此功能,您可以模拟来自远程服务器的响应,并使用一种本地 Web 服务器。

注册自定义方案

要注册自定义方案,请在配置 Engine 期间使用 EngineOptions.Builder.addScheme() 方法。这是必需的,因为 Chromium 在启动期间注册所有方案,并且在初始化后不允许修改方案。

以下代码演示了如何注册自定义方案,并关联 InterceptUrlRequestCallback 回调,该回调将在 Browser 每次使用给定方案加载资源时被调用:

Java
Kotlin

InterceptUrlRequestCallback interceptor = params -> {
    var options = UrlRequestJob.Options.newBuilder(HttpStatus.OK)
        .addHttpHeader(HttpHeader.of("Content-Type", "text/plain"))
        .build();
    var job = params.newUrlRequestJob(options);
    job.write("Hello!".getBytes());
    job.complete();
    return InterceptUrlRequestCallback.Response.intercept(job);
};
var options = EngineOptions.newBuilder(renderingMode)
    .addScheme(Scheme.of("jxb"), interceptor)
    .build();
var engine = Engine.newInstance(options);

val interceptor = InterceptUrlRequestCallback { params ->
    val options = UrlRequestJobOptions(
        status = HttpStatus.OK,
        headers = listOf(HttpHeader("Content-Type", "text/plain"))
    )
    val job = params.newUrlRequestJob(options).apply {
        write("Hello!".toByteArray())
        complete()
    }
    InterceptUrlRequestCallback.Response.intercept(job)
}
val engine = Engine(renderingMode) {
    schemes.add(Scheme("jxb"), interceptor)
}

现在,如果您加载 jxb://anyhost/anypage.html,URL 请求将被拦截,并调用关联的回调。你将得到以下输出:

Custom Scheme

拦截 HTTP/HTTPS 请求

您可以使用与注册自定义方案相同的方法来拦截标准方案,如 HTTP 或 HTTPS。在这种情况下,您需要添加相应的方案,如下所示:

Java
Kotlin

InterceptUrlRequestCallback interceptor = params -> {
    var jobOptions = UrlRequestJob.Options.newBuilder(HttpStatus.OK)
        .addHttpHeader(HttpHeader.of("Content-Type", "text/plain"))
        .build();
    var job = params.newUrlRequestJob(jobOptions);
    ...
    return InterceptUrlRequestCallback.Response.intercept(job);
};
var options = EngineOptions.newBuilder(renderingMode)
    .addScheme(Scheme.HTTPS, interceptor)
    .build();

val interceptor = InterceptUrlRequestCallback { params ->
    val options = UrlRequestJobOptions(
        status = HttpStatus.OK,
        headers = listOf(HttpHeader("Content-Type", "text/plain"))
    )
    val job = params.newUrlRequestJob(options)
    ...
    InterceptUrlRequestCallback.Response.intercept(job)
}
val engine = Engine(renderingMode) {
    schemes.add(Scheme.HTTPS, interceptor)
}

网络事件和回调

Network API 定义了一组事件和回调,跟踪了 Web 请求的生命周期。您可以使用这些事件来观察和分析流量。通过回调,您可以拦截、阻止或修改请求。

成功请求的事件生命周期如下所示: Network Events Flow

URL 请求之前

BeforeUrlRequestCallback 回调在 HTTP 请求即将发生时被调用。您可以使用此回调将请求重定向到另一个位置。例如:

Java
Kotlin

network.set(BeforeUrlRequestCallback.class, (params) ->
    BeforeUrlRequestCallback.Response.redirect("<new-url>"));

network.register(BeforeUrlRequestCallback {
    BeforeUrlRequestCallback.Response.redirect("<new-url>")
})

发送上传数据前

BeforeSendUploadDataCallback 回调在上传数据发送到 Web 服务器之前被调用。在此处,您可以覆盖上传数据。例如:

Java
Kotlin

network.set(BeforeSendUploadDataCallback.class, (params) ->
    BeforeSendUploadDataCallback.Response.override(TextData.of("<text-data>")));

network.register(BeforeSendUploadDataCallback {
    val newData = TextData("<text-data>")
    BeforeSendUploadDataCallback.Response.override(newData)
})

如果请求没有上传数据,则不会调用此回调。

支持以下 UploadData 类型:

  • BytesData 表示一个字节序列。content-type 是可配置的。
  • TextData 表示 text/plain 内容类型的数据。
  • FormData 表示 application/x-www-form-urlencoded 内容类型的数据。
  • MultipartFormData 表示 multipart/form-data 内容类型的数据。

事务开始之前

BeforeStartTransactionCallback 回调在网络事务开始之前被调用。在此回调中,您可以在发送之前添加或覆盖 HTTP 标头。例如:

Java
Kotlin

network.set(BeforeStartTransactionCallback.class, (params) -> {
    var httpHeaders = new ArrayList<>(params.httpHeaders());
    httpHeaders.add(HttpHeader.of("<header-name>", "<header-value>"));
    return BeforeStartTransactionCallback.Response.override(httpHeaders);
});

network.register(BeforeStartTransactionCallback { params ->
    val customHeader = HttpHeader("<header-name>", "<header-value>")
    val httpHeaders = params.httpHeaders() + customHeader
    BeforeStartTransactionCallback.Response.override(httpHeaders)
})

此回调不会捕获以下标头。此列表可能会有所变动,且可能不完整:

  • Authorization
  • Cache-Control
  • Connection
  • Content-Length
  • Host
  • If-Modified-Since
  • If-None-Match
  • If-Range
  • Partial-Data
  • Pragma
  • Proxy-Authorization
  • Proxy-Connection
  • Transfer-Encoding

接收标头

ReceiveHeadersCallback 回调在 HTTP 请求接收到标头时调用。您可以在此处添加、修改或删除通过网络接收的 HTTP 标头。例如:

Java
Kotlin

network.set(ReceiveHeadersCallback.class, (params) -> {
    var httpHeaders = new ArrayList<>(params.httpHeaders());
    httpHeaders.add(HttpHeader.of("<header-name>", "<header-value>"));
    return ReceiveHeadersCallback.Response.override(httpHeaders);
});

network.register(ReceiveHeadersCallback { params ->
    val customHeader = HttpHeader("<header-name>", "<header-value>")
    val httpHeaders = params.httpHeaders() + customHeader
    ReceiveHeadersCallback.Response.override(httpHeaders)
})

收到重定向响应代码

RedirectResponseCodeReceived 事件在收到请求的重定向响应代码 3xx 时触发。在此事件中,您可以获取有关重定向的详细信息,如新 URL 和响应代码。例如:

Java
Kotlin

network.on(RedirectResponseCodeReceived.class, (event) -> {
    var newUrl = event.newUrl();
    var responseCode = event.responseCode();
});

network.subscribe<RedirectResponseCodeReceived> { event ->
    val newUrl = event.newUrl()
    val responseCode = event.responseCode()
}

响应开始

ResponseStarted 事件在接收到 URL 响应正文的第一个字节时触发。对于 HTTP 请求,这意味着状态行和响应标头是可用的。在此事件中,您可以访问相应的请求和响应代码。例如:

Java
Kotlin

network.on(ResponseStarted.class, (event) -> {
    var urlRequest = event.urlRequest();
    var responseCode = event.responseCode();
});

network.subscribe<ResponseStarted> { event ->
    val urlRequest = event.urlRequest()
    val responseCode = event.responseCode()
}

请求完成

当 URL 请求成功完成或失败时,将触发 RequestCompleted 事件。在此事件中,您可以检查请求是否已启动,获取请求状态的详细信息,访问响应代码。例如:

Java
Kotlin

network.on(RequestCompleted.class, (event) -> {
    var urlRequest = event.urlRequest();
    // URL 请求状态的详细信息。
    var urlRequestStatus = event.status();
    // HTTP 响应代码。
    var responseCode = event.responseCode();
});

network.subscribe<RequestCompleted> { event ->
    val urlRequest = event.urlRequest()
    // URL 请求状态的详细信息。
    val urlRequestStatus = event.status()
    // HTTP 响应代码。
    val responseCode = event.responseCode()
}

请求销毁

RequestDestroyed 事件是在请求被销毁且不再可用时被触发。要访问已销毁请求的详细信息,请使用以下代码:

Java
Kotlin

network.on(RequestDestroyed.class, (event) -> {
    var urlRequest = event.urlRequest();
});

network.subscribe<RequestDestroyed> { event ->
    val urlRequest = event.urlRequest()
}

接收到响应字节

ResponseBytesReceived 事件在通过网络接收到 HTTP 响应正文的一部分时触发。它允许访问 HTTP 响应主体的字节:

Java
Kotlin

network.on(ResponseBytesReceived.class, event -> {
    var data = event.data();
});

network.subscribe<ResponseBytesReceived> { event ->
    val data = event.data()
}

响应主体的部分可能以随机顺序到达。在使用此事件恢复完整响应时,请记住这一点。

连接状态

Chromium 会跟踪互联网连接的状态。当网络连接断开然后恢复时,Chromium 会检测到这种变化并重新加载当前加载的网页。您可以使用以下 API 获取相应的通知:

Java
Kotlin

network.on(NetworkChanged.class, e -> {
    // 如果连接类型为 TYPE_NONE,则表示没有连接。
    if (e.connectionType() == ConnectionType.TYPE_NONE) {
        // 网络连接已断开,我们处于离线状态。
    } else {
        // 网络连接已恢复。
    }
});

network.subscribe<NetworkChanged> { event ->
    // 如果连接类型为 TYPE_NONE,则表示没有连接。
    if (event.connectionType() == ConnectionType.TYPE_NONE) {
        // 网络连接已断开,我们处于离线状态。
    } else {
        // 网络连接已恢复。
    }
}