List icon Conteúdo

Navegação

Navegação

Este guia descreve os eventos de navegação e mostra como carregar URLs e arquivos, filtrar requests de navegação, trabalhar com o histórico de navegação, etc.

Carregando URL

Para navegar para um recurso identificado por um URL, você pode utilizar um dos seguintes métodos:

  • Navigation.loadUrl(String url)
  • Navigation.loadUrl(LoadUrlParams params)

O exemplo a seguir mostra como navegar para https://www.google.com utilizando o método Navigation.loadUrl(String):

Java
Kotlin
var navigation = browser.navigation();
navigation.loadUrl("https://html5test.teamdev.com");
val navigation = browser.navigation
navigation.loadUrl("https://html5test.teamdev.com")

O código acima solicita a navegação para o recurso fornecido e sai imediatamente. Ele não espera até que o recurso seja completamente carregado.

Se for necessário bloquear a execução do thread atual até que o recurso seja carregado completamente, utilize o método Navigation.loadUrlAndWait(String url, Duration timeout):

Java
Kotlin
navigation.loadUrlAndWait("https://html5test.teamdev.com", Duration.ofSeconds(45));
navigation.loadUrlAndWait("https://html5test.teamdev.com", Duration.ofSeconds(45))

Este método bloqueia a execução do segmento atual até que o frame principal do recurso seja completamente carregado ou até que o tempo limite de 45 segundos seja atingido.

Se a navegação falhar, será lançada a exceção NavigationException.

Se o recurso não tiver sido carregado dentro de um período de tempo limite, será lançada a exceção TimeoutException.

Carregando URL com POST

Para carregar uma página da Web e enviar dados POST, use o método Navigation.loadUrl(LoadUrlParams). O seguinte código demonstra como formar os dados POST e enviá-los para o URL.

Java
Kotlin
var data = TextData.of("post data");
var params = LoadUrlParams.newBuilder(url)
    .uploadData(data)
    .addExtraHeader(HttpHeader.of("Content-Type", "text/plain"))
    .build();
navigation.loadUrl(params);
val params = LoadUrlParams(
    url = url,
    data = TextData("post data"),
    extraHeaders = listOf(HttpHeader("Content-Type", "text/plain"))
)
navigation.loadUrl(params)

Outros tipos de dados POST também estão disponíveis: MultipartFormData, FormData, ByteData.

Carregando Arquivo

Você pode utilizar os mesmos métodos para carregar arquivos HTML a partir do sistema de arquivos local. Você só precisa fornecer um caminho absoluto para o arquivo HTML em vez de um URL.

Por exemplo:

Java
Kotlin
navigation.loadUrl(new File("index.html").getAbsolutePath());
val indexPage = File("index.html")
navigation.loadUrl(indexPage.absolutePath)

Carregando HTML

Esta seção descreve como carregar HTML num Frame.

Existem duas abordagens possíveis para fazê-lo:

Estas abordagens apresentam as seguintes diferenças:

FuncionalidadeURL de DadosEsquema Personalizado
Suporte da ponte JavaScript-Javasimsim
Suporte de InjectJsCallbacksimsim
Suporte de InjectCssCallbacksimsim
Carregando <iframe> do HTTPsimsim
Carregando <iframe> do sistema de arquivosnãonão
Carregamento de imagens a partir de HTTPsimsim
Carregar imagens do sistema de arquivosnãonão
Produção de eventos em redenãosim
Produção de eventos de navegaçãosimsim
Mostrar PDF e pré-visualização de impressãosimsim
Mostrar PDF e pré-visualização de impressão em <iframe>simsim

URL de Dados

A ideia desta abordagem é converter o HTML necessário numa string base64, gerar o URI de Dados com a string convertida e carregar este URL como mostrado abaixo:

Java
Kotlin
var html = "<html><body>Hello</body></html>";
var base64Html = Base64.getEncoder().encodeToString(html.getBytes(UTF_8));
var dataUrl = "data:text/html;charset=utf-8;base64," + base64Html;
browser.navigation().loadUrl(dataUrl);
val html = "<html><body>Hello</body></html>"
val base64Html = Base64.getEncoder().encodeToString(html.toByteArray(UTF_8))
val dataUrl = "data:text/html;charset=utf-8;base64,$base64Html"
browser.navigation.loadUrl(dataUrl)

Também é possível utilizar o método Frame.loadHtml(String html), que gera automaticamente o URI de Dados a partir do HTML fornecido:

Java
Kotlin
var html = "<html><body>Hello</body></html>";
browser.mainFrame().ifPresent(frame -> frame.loadHtml(html));
val html = "<html><body>Hello</body></html>"
browser.mainFrame?.loadHtml(html)

A string URL não deve exceder o comprimento de 2MB devido ao limite do Chromium. Uma tentativa de carregar uma string URL que exceda este limite será ignorada pelo Chromium.

Esquema Personalizado

Outra abordagem para carregar HTML a partir de uma string é baseada em InterceptUrlRequestCallback. A ideia é registrar a chamada de retorno e interceptar um request de URL específico para devolver o HTML necessário como uma resposta HTTP. Por exemplo:

Java
Kotlin
InterceptUrlRequestCallback interceptCallback = params -> {
    if (params.urlRequest().url().endsWith("?hello")) {
        var bytes = "<html><body>Hello</body></html>".getBytes();
        var job = params.newUrlRequestJob(
            UrlRequestJob.Options
                .newBuilder(HttpStatus.OK)
                .addHttpHeader(HttpHeader.of("Content-Type", "text/html"))
                .build());
        job.write(bytes);
        job.complete();
        return InterceptUrlRequestCallback.Response.intercept(job);
    }
    return InterceptUrlRequestCallback.Response.proceed();
};

var options = EngineOptions.newBuilder(renderingMode)
    .addScheme(HTTP, interceptCallback)
    .build();
var engine = Engine.newInstance(options);
var browser = engine.newBrowser();
browser.navigation().loadUrl("http://load.html/?hello");
val interceptCallback = InterceptUrlRequestCallback { params ->
    if (params.urlRequest().url().endsWith("?hello")) {
        val bytes = "<html><body>Hello</body></html>".toByteArray()
        val options = UrlRequestJobOptions(
            status = HttpStatus.OK,
            headers = listOf(HttpHeader("Content-Type", "text/html"))
        )
        val job = params.newUrlRequestJob(options).apply {
            write(bytes)
            complete()
        }
        InterceptUrlRequestCallback.Response.intercept(job)
    } else {
        InterceptUrlRequestCallback.Response.proceed()
    }
}

val engine = Engine(renderingMode) {
    schemes.add(HTTP, interceptCallback)
}
val browser = engine.newBrowser()
browser.navigation.loadUrl("http://load.html/?hello")

O pedido de URL que termina com ?hello será interceptado e o HTML <html><body>Hello</body></html> será carregado no navegador.

Recarregando

Existem várias opções para recarregar a página Web atualmente carregada:

Recarregar utilizando a cache HTTP:

Java
Kotlin
navigation.reload();
navigation.reload()

Recarregar ignorando a cache HTTP:

Java
Kotlin
navigation.reloadIgnoringCache();
navigation.reloadIgnoringCache()

Recarregar utilizando a cache HTTP e verificar se há repostagem:

Java
Kotlin
navigation.reloadAndCheckForRepost();
navigation.reloadAndCheckForRepost()

Recarregar ignorando a cache HTTP e verificar se há repostagem:

Java
Kotlin
navigation.reloadIgnoringCacheAndCheckForRepost();
navigation.reloadIgnoringCacheAndCheckForRepost()

Parando

Utilize o método Navigation.stop() para cancelar qualquer operação de navegação ou download pendente e parar qualquer elemento dinâmico da página, como sons de fundo e animações. Por exemplo:

Java
Kotlin
navigation.stop();
navigation.stop()

Voltar & Avançar

O JxBrowser permite trabalhar com a lista do histórico de navegação voltar e avançar.

Quando você cria uma instância Browser ele navega para a página web about:blank por padrão, então há sempre uma entrada na lista de navegação voltar e avançar.

Para carregar a localização anterior na lista de voltar e avançar, utilize a seguinte abordagem:

Java
Kotlin
if (navigation.canGoBack()) {
    navigation.goBack();
}
if (navigation.canGoBack) {
    navigation.goBack()
}

Para carregar a localização seguinte na lista voltar e avançar, utilize:

Java
Kotlin
if (navigation.canGoForward()) {
    navigation.goForward();
}
if (navigation.canGoForward) {
    navigation.goForward()
}

Para navegar para a entrada num índice específico na lista voltar e avançar, utilize:

Java
Kotlin
if (index >= 0 && index < navigation.entryCount()) {
    navigation.goToIndex(index);
}
if (index >= 0 && index < navigation.entryCount()) {
    navigation.goToIndex(index)
}

Você pode percorrer a lista voltar e avançar e obter detalhes sobre cada entrada de navegação:

Java
Kotlin
for (int index = 0; index < navigation.entryCount(); index++) {
    var navigationEntry = navigation.entryAtIndex(index);
    System.out.println("URL: " + navigationEntry.url());
    System.out.println("Title: " + navigationEntry.title());
}
for (index in 0 until navigation.entryCount()) {
    val navigationEntry = navigation.entryAtIndex(index)
    println("URL: ${navigationEntry.url()}")
    println("Title: ${navigationEntry.title()}")
}

Você pode modificar a lista voltar e avançar removendo as entradas:

Java
Kotlin
// Devolve o número de entradas na lista de voltar/avançar.
var entryCount = navigation.entryCount();
// Remover entradas de navegação no índice.
for (int i = entryCount - 2; i >= 0; i--) {
    var success = navigation.removeEntryAtIndex(i);
    System.out.println("A entrada de navegação no índice " + i +
        " foi removida com êxito? " + success);
}
// Retorna o número de entradas na lista de retrocesso/avanço.
val entryCount = navigation.entryCount()
// Remover entradas de navegação no índice.
for (i in entryCount - 2 downTo 0) {
    val success = navigation.removeEntryAtIndex(i)
    println("A entrada de navegação no índice $i foi removida com êxito? $success")
}

Filtragem de URLs

Você pode decidir se o request de navegação para um URL específico deve ser ignorado ou não.

O código seguinte demonstra como ignorar os requests de navegação para todos os URLs que começam por https://www.google:

Java
Kotlin
navigation.set(StartNavigationCallback.class, params -> {
    // Ignore solicitações de navegação
    // para URLs que começam com "https://www.google".
    if (params.url().startsWith("https://www.google")) {
        return StartNavigationCallback.Response.ignore();
    }
    return StartNavigationCallback.Response.start();
});
navigation.register(StartNavigationCallback { params ->
    // Ignore solicitações de navegação
    // para URLs que começam com "https://www.google".
    if (params.url().startsWith("https://www.google")) {
        StartNavigationCallback.Response.ignore()
    } else {
        StartNavigationCallback.Response.start()
    }
})

Filtragem de Recursos

Utilizando a chamada de retorno BeforeUrlRequestCallback você pode determinar se os recursos como HTML, imagem, arquivo JavaScript ou CSS, favicon, etc. devem ser carregados. Por padrão, todos os recursos são carregados. Para modificar o comportamento padrão, registre a sua própria implementação de retorno de chamada onde você decide quais recursos devem ser cancelados ou carregados.

O exemplo seguinte demonstra como suprimir todas as imagens:

Java
Kotlin
var network = engine.network();
network.set(BeforeUrlRequestCallback.class, params -> {
    if (params.urlRequest().resourceType() == IMAGE) {
        return BeforeUrlRequestCallback.Response.cancel();
    }
    return BeforeUrlRequestCallback.Response.proceed();
});
val network = engine.network
network.register(BeforeUrlRequestCallback { params ->
    if (params.urlRequest().resourceType() === IMAGE) {
        BeforeUrlRequestCallback.Response.cancel()
    } else {
        BeforeUrlRequestCallback.Response.proceed()
    }
})

Eventos de Navegação

O carregamento de uma página Web é um processo complexo durante o qual são acionados diferentes eventos de navegação. O diagrama seguinte mostra a ordem pela qual os eventos de navegação podem ser acionados durante o carregamento de uma página Web: Fluxo de eventos de navegação

Carregamento Iniciado

Para receber notificações quando o carregamento do conteúdo tiver começado, utilize o evento LoadStarted. Por exemplo:

Java
Kotlin
navigation.on(LoadStarted.class, event -> {});
navigation.subscribe<LoadStarted> { event -> }

Este evento corresponde ao momento em que o spinner da aba começa a rodar.

Carregamento Concluído

Para receber notificações quando o carregamento do conteúdo tiver terminado, utilize o evento LoadFinished. Por exemplo:

Java
Kotlin
navigation.on(LoadFinished.class, event -> {});
navigation.subscribe<LoadStarted> { event -> }

Este evento corresponde ao momento em que o spinner do separador para de rodar.

Navegação Iniciada

Para receber notificações sobre o início da navegação, utilize o evento NavigationStarted. Por exemplo:

Java
Kotlin
navigation.on(NavigationStarted.class, event -> {
    var url = event.url();
    // Indica se a navegação será realizada
    // no escopo do mesmo documento.
    var isSameDocument = event.isSameDocument();
});
navigation.subscribe<NavigationStarted> { event ->
    val url = event.url()
    // Indica se a navegação será realizada
    // no escopo do mesmo documento.
    val isSameDocument = event.isSameDocument
}

Navegação Interrompida

Para receber notificações quando a navegação for interrompida, utilize o evento NavigationStopped. Por exemplo:

Java
Kotlin
navigation.on(NavigationStopped.class, event -> {});
navigation.subscribe<NavigationStopped> { event -> }

Este evento é disparado quando a navegação é interrompida através do método Navigation.stop().

Navegação Redirecionada

Para receber notificações quando a navegação tiver sido redirecionada para um novo URL, utilize o evento NavigationRedirected. Por exemplo:

Java
Kotlin
navigation.on(NavigationRedirected.class, event -> {
    // O URL de redirecionamento da navegação.
    var url = event.destinationUrl();
});
navigation.subscribe<NavigationRedirected> { event ->
    // O URL de redirecionamento da navegação.
    val url = event.destinationUrl()
}

Navegação Concluída

Para receber notificações quando a navegação tiver terminado, utilize o evento NavigationFinished. Por exemplo:

Java
Kotlin
navigation.on(NavigationFinished.class, event -> {
    var url = event.url();
    var frame = event.frame();
    var hasCommitted = event.hasCommitted();
    var isSameDocument = event.isSameDocument();
    var isErrorPage = event.isErrorPage();
    if (isErrorPage) {
        var error = event.error();
    }
});
navigation.subscribe<NavigationFinished> { event ->
    val url = event.url()
    val frame = event.frame()
    val hasCommitted = event.hasCommitted()
    val isSameDocument = event.isSameDocument
    val isErrorPage = event.isErrorPage
    if (isErrorPage) {
        val error = event.error()
    }
}

Este evento é ativado quando a navegação é confirmada, abortada ou substituída por uma nova. Para saber se a navegação foi confirmada, utilize NavigationFinished.hasCommitted(); utilize NavigationFinished.isErrorPage() para saber se a navegação resultou em uma página de erro.

Se o evento for chamado porque a navegação foi comprometida, o carregamento do documento ainda estará em curso.

O evento é disparado por navegações do tipo mesmo documento (no escopo do mesmo documento), como navegações de fragmentos ou window.history.pushState()/window.history.replaceState(), que não resultarão em uma mudança de documento. Utilize NavigationFinished.isSameDocument() para verificar se a navegação é do mesmo documento.

Carregamento do Frame Concluído

Para receber notificações quando o conteúdo carregado no Frame tiver terminado, por favor use o evento FrameLoadFinished. Por exemplo:

Java
Kotlin
navigation.on(FrameLoadFinished.class, event -> {
    var url = event.url();
    var frame = event.frame();
});
navigation.subscribe<FrameLoadFinished> { event ->
    val url = event.url()
    val frame = event.frame()
}

Este evento corresponde ao momento em que o conteúdo do Frame foi completamente carregado.

Falha no Carregamento do Frame

Para receber notificações quando o conteúdo carregado no Frame falhou por algum motivo, use o evento FrameLoadFailed. Por exemplo:

Java
Kotlin
navigation.on(FrameLoadFailed.class, event -> {
    var url = event.url();
    var error = event.error();
});
navigation.subscribe<FrameLoadFailed> { event ->
    val url = event.url()
    val error = event.error()
}

Carregamento do Documento Frame Concluído

Para receber notificações quando o carregamento do documento Frame tiver terminado, por favor use o evento FrameDocumentLoadFinished. Por exemplo:

Java
Kotlin
navigation.on(FrameDocumentLoadFinished.class, event -> {
    var frame = event.frame();
});
navigation.subscribe<FrameDocumentLoadFinished> { event ->
    val frame = event.frame()
}

Nesta altura, os scripts diferidos foram executados e os scripts de conteúdo marcados com “document_end” são injetados no frames.