Migração da versão 2.4 para a 2.5

No DotNetBrowser 2.5, o engine Chromium foi atualizado para a versão 88. Esta versão do Chromium tem várias alterações de ruptura no código fonte que afetam a API pública do produto. Neste guia de migração, descrevemos qual a API que foi removida/alterada na versão 2.5 e quais as alternativas que deve utilizar.

API removida

Suporte para Flash

No Chromium 88, o suporte para Flash foi abandonado, assim as opções de engine a seguir se tornaram obsoletas e foram removidas da API:

  • EngineOptions.PpapiFlashPath
  • EngineOptions.PpapiFlashVersion

Idiomas da IU

Os seguintes idiomas da IU foram removidos, uma vez que já não são oficialmente suportados pelo Chromium:

  • Africâner
  • Chinês (Hong Kong)
  • Francês (Canadá)
  • Inglês (Austrália)
  • Zulu

API adicionada ou atualizada

Rede

Interceptação de pedidos

v2.4

Para interceptar pedidos de URL com os esquemas padrão (por exemplo, http, https) e personalizados (por exemplo, my-app) foi utilizado o InterceptRequestHandler. Ele permite interceptar pedidos e substituir dados de resposta como se fossem enviados por um servidor Web.

Eis como interceptar pedidos com o esquema myscheme na versão 2.4:

engine.Network.InterceptRequestHandler =
    new Handler<InterceptRequestParameters, InterceptRequestResponse>(p =>
    {
        if(!p.UrlRequest.Url.StartsWith("myscheme"))
        {
            return InterceptRequestResponse.Proceed();
        }
        UrlRequestJobOptions options = new UrlRequestJobOptions
        {
            Headers = new List<HttpHeader>
            {
                new HttpHeader("Content-Type", "text/html", "charset=utf-8"),
            }
        };
        UrlRequestJob job = p.Network.CreateUrlRequestJob(p.UrlRequest, options);

        Task.Run((() =>
        {
            // O processamento do pedido é efetuado numa thread em segundo plano
            // para evitar o congelamento da página Web.
            job.Write(Encoding.UTF8.GetBytes("My data"));
            job.Complete();
        });
        
        return InterceptRequestResponse.Intercept(job);
    });
...

browser.Navigation.LoadUrl("myscheme://app/hello");
engine.Network.InterceptRequestHandler = 
    New Handler(Of InterceptRequestParameters, InterceptRequestResponse)(Function(p)
        If Not p.UrlRequest.Url.StartsWith("myscheme") Then
            Return InterceptRequestResponse.Proceed()
        End If
        Dim options As New UrlRequestJobOptions With {
            .Headers = New List(Of HttpHeader) From {
                New HttpHeader("Content-Type", "text/html", "charset=utf-8")}
        }
        Dim job As UrlRequestJob = p.Network.CreateUrlRequestJob(p.UrlRequest, options)

        Task.Run(Sub()
            ' O processamento do pedido é efetuado numa thread em segundo plano
            ' para evitar o congelamento da página Web.
            job.Write(Encoding.UTF8.GetBytes("My data"))
            job.Complete()
        End Sub)

        Return InterceptRequestResponse.Intercept(job)
    End Function)

'...

browser.Navigation.LoadUrl("myscheme://app/hello")

v2.5

A abordagem anterior, que consiste em interceptar todos os pedidos, tem várias limitações e problemas de segurança:

  • os esquemas personalizados interceptados são tratados como não-padrão, já que não é possível interceptar um esquema personalizado e devolver HTML com JavaScript que acesse a LocalStorage. Isto conduzirá a um erro de acesso negado;
  • nem todos os esquemas podem ser interceptados. Por exemplo, é proibido interceptar esquemas como chrome, data, ou chrome-extensions. A versão anterior da API permite fazer isto, o que pode levar a um comportamento inesperado ou a uma falha no Chromium;
  • alguns sistemas são tratados como sistemas locais, por exemplo, file. Eles não podem ser interceptados porque não se trata de um pedido de rede.

Nesta versão, melhorámos a API que permite interceptar pedidos de URL e registrar esquemas personalizados. A nova versão não tem as limitações de segurança e os problemas descritos acima.

O exemplo seguinte demonstra como registrar o esquema personalizado myscheme e interceptar todos os pedidos de URL correspondentes:

var handler = new Handler<InterceptRequestParameters, InterceptRequestResponse>(p =>
{
    UrlRequestJobOptions options = new UrlRequestJobOptions
    {
        Headers = new List<HttpHeader>
        {
            new HttpHeader("Content-Type", "text/html", "charset=utf-8"),
        }
    };
    UrlRequestJob job = p.Network.CreateUrlRequestJob(p.UrlRequest, options);

    Task.Run((() =>
    {
        // O processamento do pedido é efetuado numa thread em segundo plano
        // para evitar o congelamento da página Web.
        job.Write(Encoding.UTF8.GetBytes("My data"));
        job.Complete();
    });

    return InterceptRequestResponse.Intercept(job);
});

IEngine engine = EngineFactory.Create(new EngineOptions.Builder
{
    Schemes =
    {
        { Scheme.Create("myscheme"), handler }
    }
}.Build());

IBrowser browser = engine.CreateBrowser();

browser.Navigation.LoadUrl("myscheme://app/hello");
Dim handler As New Handler(
    Of InterceptRequestParameters, InterceptRequestResponse)(Function(p)
    Dim options As New UrlRequestJobOptions With {
        .Headers = New List(Of HttpHeader) From {
            New HttpHeader("Content-Type", "text/html", "charset=utf-8")}
    }
    Dim job As UrlRequestJob = p.Network.CreateUrlRequestJob(p.UrlRequest, options)

    Task.Run(Sub()
        ' O processamento do pedido é efetuado numa thread em segundo plano
        ' para evitar o congelamento da página Web.
        job.Write(Encoding.UTF8.GetBytes("My data"))
        job.Complete()
    End Sub)

    Return InterceptRequestResponse.Intercept(job)
End Function)

Dim engine As IEngine = EngineFactory.Create(New EngineOptions.Builder With {
    .Schemes = {
        { Scheme.Create("myscheme"), handler }
    }
}.Build())

Dim browser As IBrowser = engine.CreateBrowser()

browser.Navigation.LoadUrl("myscheme://app/hello")

Se o esquema especificado não puder ser interceptado, a exceção correspondente será lançada pelo construtor EngineOptions. Por exemplo: “O esquema “file” não pode ser interceptado.”

Limitações conhecidas

As restrições de segurança tornaram-se mais firmes no Chromium 88. Como resultado, quando um documento HTML que depende de scripts externos é carregado utilizando LoadHtml, ele nunca carrega esses scripts e registra erros dizendo Failed to load resource: net::ERR_NOT_IMPLEMENTED.

A solução possível é utilizar data: encoded URI e depois carregá-lo utilizando a chamada LoadUrl normal. Eis um exemplo:

var html = "<html><head></head><body><h1>Html codificado no URL!</h1></body></html>";
var base64EncodedHtml = Convert.ToBase64String(Encoding.UTF8.GetBytes(html));
browser.Navigation.LoadUrl("data:text/html;base64," + base64EncodedHtml).Wait();
Dim html = "<html><head></head><body><h1>Html codificado no URL!</h1></body></html>"
Dim base64EncodedHtml = Convert.ToBase64String(Encoding.UTF8.GetBytes(html))
browser.Navigation.LoadUrl("data:text/html;base64," & base64EncodedHtml).Wait()

No entanto, o URL de base não pode ser definido quando se utiliza esta solução alternativa.

Outra abordagem possível é registrar um Scheme com um handler e interceptar o pedido correspondente para fornecer o HTML. Veja o artigo correspondente.

Go Top