Chế độ không có giao diện người dùng của Chrome

Peter Kvitek
Peter Kvitek

Vào năm 2017, Chrome 59 đã giới thiệu Chế độ không có giao diện người dùng, cho phép bạn chạy trình duyệt trong môi trường không được giám sát mà không có bất kỳ giao diện người dùng nào hiển thị. Về cơ bản, bạn có thể chạy Chrome mà không cần Chrome.

Chế độ không có giao diện người dùng là một lựa chọn phổ biến cho hoạt động tự động hoá trình duyệt, thông qua các dự án như Puppeteer hoặc ChromeDriver. Dưới đây là ví dụ tối thiểu về dòng lệnh, dùng chế độ Không có giao diện người dùng để tạo tệp PDF của một URL nhất định:

chrome --headless --print-to-pdf https://developer.chrome.com/

Cách hoạt động của giao diện người dùng không có giao diện người dùng

Trước khi xem xét cách hoạt động hiện tại của Headless, bạn cần hiểu cách hoạt động của Headless "cũ". Đoạn mã dòng lệnh trước đó sử dụng cờ dòng lệnh --headless, cho thấy Headless chỉ là một chế độ hoạt động của trình duyệt Chrome thông thường. Có thể đáng ngạc nhiên khi điều này không thực sự đúng. Trên thực tế, Headless cũ là một cách triển khai trình duyệt thay thế, riêng biệt tình cờ được vận chuyển dưới dạng một phần của cùng một tệp nhị phân Chrome. Công cụ này không chia sẻ bất kỳ mã trình duyệt Chrome nào trong //chrome.

Việc triển khai và duy trì một trình duyệt không có giao diện người dùng riêng biệt gây ra nhiều mức hao tổn kỹ thuật. Ngoài ra, do Headless là một cách triển khai riêng biệt, nên phiên bản này có các lỗi và tính năng riêng không có trong Chrome Headless. Điều này gây nhầm lẫn cho các hoạt động kiểm thử trình duyệt tự động, có thể chuyển ở chế độ hiển thị thông tin chính xác nhưng không thành công ở chế độ Không có giao diện người dùng hoặc ngược lại.

Ngoài ra, Headless đã loại trừ mọi hoạt động kiểm thử tự động dựa vào việc cài đặt tiện ích của trình duyệt. Tương tự như với mọi hàm cấp trình duyệt khác; trừ phi Headless có phương thức triển khai riêng và riêng biệt, thì hàm này sẽ không được hỗ trợ.

Nhóm Chrome hiện đã hợp nhất chế độ không có giao diện người dùng và chế độ có giao diện người dùng.

Giao diện Chrome Headless mới không còn là một cách triển khai riêng biệt cho trình duyệt, mà giờ đây dùng chung mã với Chrome.

Chế độ không có giao diện người dùng mới hiện đã có trên Chrome 112. Ở chế độ này, Chrome sẽ tạo nhưng không hiển thị bất kỳ cửa sổ nền tảng nào. Tất cả các hàm khác, hiện có và trong tương lai, đều có sẵn mà không có giới hạn nào.

Sử dụng Chế độ không có giao diện người dùng

Để sử dụng Chế độ không có giao diện người dùng mới, hãy truyền cờ hiệu dòng lệnh --headless=new:

chrome --headless=new

Hiện tại, chế độ Không có giao diện người dùng cũ vẫn dùng được với:

chrome --headless=old

Trong Puppeteer

Cách chọn sử dụng chế độ Không có giao diện người dùng mới trong Puppeteer:

import puppeteer from 'puppeteer';

const browser = await puppeteer.launch({
  headless: 'new',
  // `headless: true` (default) enables old Headless;
  // `headless: 'new'` enables new Headless;
  // `headless: false` enables "headful" mode.
});

const page = await browser.newPage();
await page.goto('https://developer.chrome.com/');

// …

await browser.close();

Trong Selenium-WebDriver

Cách sử dụng chế độ Không có giao diện người dùng mới trong Selenium-WebDriver:

const driver = await env
  .builder()
  .setChromeOptions(options.addArguments('--headless=new'))
  .build();

await driver.get('https://developer.chrome.com/');

// …

await driver.quit();

Hãy xem bài đăng trên blog của nhóm Serenium để biết thêm thông tin, bao gồm cả các ví dụ về cách sử dụng các liên kết ngôn ngữ khác.

Cờ hiệu dòng lệnh

Các cờ dòng lệnh sau đây hiện đã có trong chế độ Không có giao diện người dùng mới.

--dump-dom

Cờ --dump-dom in DOM được chuyển đổi tuần tự của trang đích sang stdout. Ví dụ:

chrome --headless=new --dump-dom https://developer.chrome.com/

Thao tác này khác với việc in mã nguồn HTML mà bạn có thể thực hiện bằng curl. Để cung cấp cho bạn kết quả của --dump-dom, trước tiên, Chrome phân tích cú pháp mã HTML thành một DOM, thực thi bất kỳ <script> nào có thể thay đổi DOM, sau đó chuyển DOM đó trở lại thành một chuỗi HTML được chuyển đổi tuần tự.

--screenshot

Cờ --screenshot chụp ảnh màn hình trang đích và lưu trang đó dưới dạng screenshot.png trong thư mục đang làm việc. Điều này đặc biệt hữu ích khi kết hợp với cờ --window-size.

Ví dụ:

chrome --headless=new --screenshot --window-size=412,892 https://developer.chrome.com/

--print-to-pdf

Cờ --print-to-pdf lưu trang đích dưới dạng tệp PDF có tên output.pdf trong thư mục đang làm việc. Ví dụ:

chrome --headless=new --print-to-pdf https://developer.chrome.com/

Nếu muốn, bạn có thể thêm cờ --no-pdf-header-footer để bỏ qua tiêu đề in (có ngày và giờ hiện tại) và chân trang (có URL và số trang).

chrome --headless=new --print-to-pdf --no-pdf-header-footer https://developer.chrome.com/

Không: Chức năng phía sau cờ --no-pdf-header-footer trước đây có sẵn với cờ --print-to-pdf-no-header. Bạn có thể cần quay lại tên cờ cũ nếu sử dụng phiên bản trước đó.

--timeout

Cờ --timeout xác định thời gian chờ tối đa (tính bằng mili giây) mà sau đó nội dung của trang được --dump-dom, --screenshot--print-to-pdf ghi lại ngay cả khi trang vẫn đang tải.

chrome --headless=new --print-to-pdf --timeout=5000 https://developer.chrome.com/

Cờ --timeout=5000 yêu cầu Chrome đợi tối đa 5 giây trước khi in tệp PDF. Do đó, quá trình này sẽ mất tối đa 5 giây để chạy.

--virtual-time-budget

--virtual-time-budget đóng vai trò "tua nhanh" đối với bất kỳ mã phụ thuộc vào thời gian nào (ví dụ: setTimeout/setInterval). Mã này buộc trình duyệt thực thi bất kỳ mã nào trên trang nhanh nhất có thể, đồng thời khiến trang tin rằng thời gian thực sự đã trôi qua.

Để minh hoạ cách sử dụng API này, hãy xem bản minh hoạ này. Bản minh hoạ này tăng, ghi nhật ký và hiển thị bộ đếm mỗi giây bằng setTimeout(fn, 1000). Sau đây là mã liên quan:

<output>0</output>
<script>
  const element = document.querySelector('output');
  let counter = 0;
  setInterval(() => {
    counter++;
    console.log(counter);
    element.textContent = counter;
  }, 1_000);
</script>

Sau một giây, trang chứa "1"; sau hai giây, "2", v.v. Dưới đây là cách bạn sẽ ghi lại trạng thái của trang sau 42 giây và lưu trạng thái dưới dạng PDF:

chrome --headless=new --print-to-pdf --virtual-time-budget=42000 https://mathiasbynens.be/demo/time

--allow-chrome-scheme-url

Bắt buộc phải có cờ --allow-chrome-scheme-url để truy cập vào các URL chrome://. Cờ này hiện có trên Chrome 123. Ví dụ:

chrome --headless=new --print-to-pdf --allow-chrome-scheme-url chrome://gpu

Gỡ lỗi

Vì Chrome thực sự ẩn ở chế độ Không có giao diện người dùng nên có vẻ khó giải quyết vấn đề. Bạn có thể gỡ lỗi Chrome không có giao diện người dùng theo cách rất giống với Chrome có giao diện người dùng.

Chạy Chrome ở Chế độ không có giao diện người dùng bằng cờ hiệu dòng lệnh --remote-debugging-port.

chrome --headless=new --remote-debugging-port=0 https://developer.chrome.com/

Thao tác này sẽ in một URL WebSocket duy nhất tới stdout, ví dụ:

DevTools listening on ws://127.0.0.1:60926/devtools/browser/b4bd6eaa-b7c8-4319-8212-225097472fd9

Trong một phiên bản Chrome quan trọng, chúng tôi có thể sử dụng tính năng gỡ lỗi từ xa Công cụ của Chrome cho nhà phát triển để kết nối với mục tiêu Không có giao diện người dùng và kiểm tra mục tiêu đó.

  1. Chuyển đến chrome://inspect rồi nhấp vào nút Configure... (Định cấu hình).
  2. Nhập địa chỉ IP và số cổng từ URL WebSocket.
    • Trong ví dụ trước, tôi đã nhập 127.0.0.1:60926.
  3. Nhấp vào Xong. Bạn sẽ thấy một Mục tiêu từ xa xuất hiện cùng với tất cả các thẻ và mục tiêu khác được liệt kê.
  4. Nhấp vào kiểm tra để truy cập vào Công cụ của Chrome cho nhà phát triển và kiểm tra mục tiêu không có giao diện người dùng từ xa, bao gồm cả chế độ xem trực tiếp của trang.

Công cụ của Chrome cho nhà phát triển có thể kiểm tra một trang đích từ xa Không có giao diện người dùng

Ý kiến phản hồi

Chúng tôi rất mong nhận được ý kiến phản hồi của bạn về chế độ Không có giao diện người dùng mới. Nếu gặp vấn đề, hãy báo cáo lỗi.