rust

How to load a html from memory to headless Chrome with Rust?


I have a html text that I get after parse it with Handlebars

let mut handlebars = Handlebars::new();
let source = fs::read_to_string("receipt-template.html").unwrap();
handlebars.register_template_string("t1", source).unwrap();
let mut data = BTreeMap::new();
data.insert("name".to_string(), "世界!".to_string());

// this variable contains <html>....</html> that I want to load into headless chrome
let html = handlebars.render("t1", &data).unwrap();

As far as I know from headless chrome documentation here, it can only load a website URL such as "https://www.wikipedia.org".

let browser = Browser::default()?;
let tab = browser.new_tab()?;

/// Navigate to wikipedia
tab.navigate_to("https://www.wikipedia.org")?;

Is it possible to use headless chrome to load html string that is stored inside a variable/memory?

I know it's possible in Node.js as I use puppeteer.setContent(html).

/// NODE.JS
const launchOptions = { executablePath }
const browser = await puppeteer.launch(launchOptions)
const page = await browser.newPage()
await page.setContent(html) // this sets the browser content into html variable directly without the use of file

Solution

  • Yes its possible to load a HTML string.

    In Chrome you can load HTML directly using a data-URI / the data protocol like so: data:text/html;charset=utf-8,<Here goes your UTF8 encoded HTML>.

    Therefore all you really need is the tab.navigate_to method.

    Here is a full example:

    use headless_chrome::{Browser, protocol::cdp::Page};
    
    fn load_html_string() -> Result<(), Box<dyn std::error::Error>> {
        let browser = Browser::default()?;
    
        let tab = browser.new_tab()?;
    
        let html = r##"
        <!DOCTYPE html>
        <html lang="en">
        <head>
            <meta charset="UTF-8">
            <meta http-equiv="X-UA-Compatible" content="IE=edge">
            <meta name="viewport" content="width=device-width, initial-scale=1.0">
            <title>Hello World</title>
        </head>
        <body>
            <h1>Hello World!</h1>
        </body>
        </html>
        "##;
    
        tab.navigate_to(format!("data:text/html;charset=utf-8,{}", html).as_str())?;
    
        let jpeg_data = tab.capture_screenshot(
            Page::CaptureScreenshotFormatOption::Jpeg,
            Some(75),
            None,
            true)?;
    
        std::fs::write("hello_world.jpeg", jpeg_data)?;
    
        Ok(())
    }
    
    fn main() {
        load_html_string().unwrap();
    }
    

    It will generate a new JPEG in your cargo root directory of the "Hello World" page.