Bản nâng cấp dành cho Chế độ không có giao diện người dùng của Chrome: giới thiệu --headless=new

Chế độ Không có giao diện người dùng của Chrome đã tốt hơn rất nhiều!

Peter Kvitek
Peter Kvitek

Chế độ Không có giao diện người dùng của Chrome đã tốt hơn rất nhiều! Bài viết này trình bày thông tin tổng quan về các nỗ lực kỹ thuật gần đây nhằm giúp Headless trở nên hữu ích hơn cho các nhà phát triển bằng cách đưa Headless đến gần hơn với chế độ "headless" thông thường của Chrome.

Thông tin khái quát

Quay trở lại năm 2017, Chrome 59 đã ra mắt chế độ có tên là 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 hiển thị nào. Về cơ bản, 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 để 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ụ dòng lệnh tối thiểu về việc sử dụng chế độ Không có giao diện người dùng để tạo tệp PDF của một URL cụ thể:

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

Có gì mới trong Headless?

Trước khi tìm hiểu chi tiết về các cải tiến gần đây của Headless, chúng ta cần hiểu rõ cách hoạt động của Headless "cũ". Đoạn mã dòng lệnh chúng tôi trình bày trước đó sử dụng cờ dòng lệnh --headless, cho thấy rằng Headless chỉ là một chế độ hoạt động của trình duyệt Chrome thông thường. Có lẽ đáng ngạc nhiên là điều này không thực sự đúng. Về mặt kỹ thuật, headless cũ là một cách triển khai riêng biệt, thay thế cho trình duyệt và được gửi đi dưới dạng một phần của cùng tệp nhị phân của Chrome. Tính năng này không dùng chung mã trình duyệt Chrome trong //chrome.

Như bạn có thể tưởng tượng, việc triển khai và duy trì trình duyệt không có giao diện người dùng riêng biệt này tốn rất nhiều chi phí kỹ thuật — nhưng đó không phải là vấn đề duy nhất. Vì Headless là một bản triển khai riêng biệt, nên nó có các lỗi và tính năng riêng mà không có trong Chrome tính năng giao diện người dùng. Điều này đã tạo ra một tình huống khó hiểu, trong đó mọi bài kiểm thử trình duyệt tự động đều có thể vượt qua được ở chế độ có hỗ trợ giao diện người dùng nhưng lại không thành công ở chế độ Không có giao diện người dùng hoặc ngược lại — một vấn đề lớn đối với các kỹ sư tự động hoá. Chính sách này cũng loại trừ mọi hoạt động thử nghiệm tự động liên quan đến việc cài đặt một tiện ích của trình duyệt, chẳng hạn như. Mọi chức năng khác ở cấp trình duyệt cũng tương tự như vậy: trừ phi Headless có cách triển khai riêng, tính năng này sẽ không được hỗ trợ.

Vào năm 2021, nhóm Chrome đã bắt tay vào giải quyết vấn đề này và hợp nhất các chế độ Không có giao diện người dùng và giao diện người dùng một lần cho tất cả.

Chrome Headless mới không còn là một triển khai trình duyệt riêng biệt nữa mà thay vào đó sẽ chia sẻ mã với Chrome.

Chúng tôi rất vui được thông báo rằng chế độ Không có giao diện người dùng mới hiện đã có trong 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 chức năng khác, hiện có và trong tương lai, đều sẵn dùng mà không có giới hạn.

Dùng thử giao diện Headless mới

Để dùng thử chế độ Không có giao diện người dùng mới, hãy chuyển cờ dòng lệnh --headless=new:

chrome --headless=new

Hiện tại, bạn vẫn có thể sử dụng chế độ Không có giao diện người dùng cũ thông qua:

chrome --headless=old

Hiện tại, việc truyền cờ dòng lệnh --headless mà không có giá trị rõ ràng vẫn sẽ kích hoạt chế độ Headless cũ — nhưng chúng tôi dự định thay đổi chế độ mặc định này thành Headless mới theo thời gian.

Chúng tôi dự định xoá hoàn toàn Headless cũ khỏi tệp nhị phân của Chrome và ngừng hỗ trợ chế độ này trong Puppeteer vào cuối năm nay. Trong quá trình xoá này, chúng tôi sẽ cung cấp Headless cũ dưới dạng một tệp nhị phân độc lập riêng cho những người dùng chưa nâng cấp được.

Trò chơi không đầu mới trong Puppeteer

Để 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();

Giao diện người dùng mới không có giao diện người dùng trong Selenium-WebDriver

Cách sử dụng chế độ Headless 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 Selenium để biết thêm thông tin, bao gồm cả ví dụ bằng cách sử dụng các liên kết ngôn ngữ khác.

Cờ dòng lệnh dành riêng cho giao diện không có giao diện người dùng

Các cờ dòng lệnh sau có sẵn cho chế độ Không có giao diện người dùng mới.

--dump-dom

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

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

Lưu ý rằng thao tác này khác với việc chỉ in mã nguồn HTML (bạn có thể làm với 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 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 của trang đích rồi lưu dưới dạng screenshot.png trong thư mục đang hoạt động. Thao tác 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 hoạt động. 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 (với ngày và giờ hiện tại) và chân trang (với URL và số trang).

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

--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 rồi mới in tệp PDF. Do đó, quá trình này chỉ mất tối đa 5 giây để chạy.

--virtual-time-budget

--virtual-time-budget cho phép du hành thời gian! Chà, ở một mức độ nào đó. Thời gian ảo hoạt động như một "Tua đi" đối với mã phụ thuộc vào thời gian bất kỳ (ví dụ: setTimeout/setInterval). Thời gian ảo buộc trình duyệt thực thi bất kỳ mã nào của 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 công cụ này, hãy xem xét trang minh hoạ này. Đây là trang tăng dần, ghi nhật ký và hiện bộ đếm mỗi giây bằng setTimeout(fn, 1000). Dưới đâ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 sẽ chứa "1"; sau hai giây, "2", v.v. Dưới đây là cách bạn sẽ chụp lại trạng thái của trang sau 42 giây và lưu dưới dạng PDF:

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

--allow-chrome-scheme-url

Cần có cờ --allow-chrome-scheme-url để truy cập chrome:// URL. Cờ này bắt đầu có trong 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ẻ rất khó để nhận biết điều gì đang xảy ra trong trường hợp có vấn đề. Thật may là bạn có thể gỡ lỗi giao diện người dùng của Chrome theo cách tương tự như Chrome. Bí quyết thành công là chạy Chrome ở chế độ Không có giao diện người dùng bằng cờ 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 có giao diện người dùng thông thường, chúng ta 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 đó. Để thực hiện việc này, hãy truy cập chrome://inspect, nhấp vào nút Configure... (Định cấu hình...) rồi nhập địa chỉ IP và số cổng từ URL WebSocket. Trong ví dụ trên, tôi đã nhập 127.0.0.1:60926. Nhấp vào Xong và 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ê bên dưới. Nhấp vào inspect và bạn hiện có quyền truy cập vào Công cụ của Chrome cho nhà phát triển để kiểm tra mục tiêu Không có giao diện người dùng từ xa, inspect!

Công cụ của Chrome cho nhà phát triển có thể kiểm tra 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 được nghe ý 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 bạn gặp bất kỳ vấn đề nào, vui lòng báo cáo vấn đề đó.