Tìm hiểu và xác định bài toán
Giới thiệu chung
Trước khi chúng ta thưởng thức một món ăn hay một loại sơn hào hải vị nào đó, chúng ta cần lên công thức và chế biến nó, cộng hưởng nó với những gia vị của nhân gian Thưởng thức nó, cảm nhận những mỹ vị của nó… Một sản phẩm web hay app cũng vậy! Chúng ta cần xác định bài toán cho một sản phẩm: “Nó cần gì, nó sẽ đạt được những gì? Kết quả là thế nào, nó có sánh ngang với sơn hào hải vị không? ” Sau đó, tìm hiểu những công nghệ để chế biến nên một sản phẩm hoàn hảo… Còn chờ gì nữa, chúng ta cùng đi ngay vào bài toán này nào!
Bài toán về trình duyệt web
Browser là một phần mềm hiển thị nội dung trang web Nhiệm vụ của nó là tải về một trang web và biểu diễn lại trang đó để người dùng có thể xem và hiểu được Về cơ bản tất cả những gì chúng ta biết về hoạt động của browser đến lúc này là:
- Người dùng nhập đường dẫn trang web vào thanh địa chỉ của browser.
- Browser tải xuống các "tài liệu" từ địa chỉ đó và hiển thị chúng.
Nó sẽ đảm nhận các công việc sau: o Phân giải DNS. o Truyền HTTP. o Hiển thị. o Lặp lại các công việc trên.
Các công nghệ
- Qt là tập hợp các thư viện C đa nền tảng triển khai các API cấp cao để truy cập nhiều khía cạnh của hệ thống máy tính để bàn và thiết bị di động hiện đại Chúng bao gồm các dịch vụ định vị và định vị, đa phương tiện, kết nối NFC và Bluetooth, trình duyệt web dựa trên Chromium, cũng như phát triển giao diện người dùng truyền thống.
- PyQt5 là một tập hợp toàn diện các ràng buộc Python cho Qt v5 Nó được triển khai dưới dạng hơn 35 mô-đun mở rộng và cho phép Python được sử dụng như một ngôn ngữ phát triển ứng dụng thay thế cho C trên tất cả các nền tảng được hỗ trợ bao gồm iOS và Android.
- PyQt5 cũng có thể được nhúng trong các ứng dụng dựa trên C để cho phép người dùng các ứng dụng đó cấu hình hoặc nâng cao chức năng của các ứng dụng đó.
- NodeJS là một nền tảng được xây dựng trên “V8 Javascript Engine” được viết bằng C++ và Javascript Nền tảng này được phát triển bởi Ryan Lienhart Dahl vào năm 2009.
- Node.js ra đời khi các Developer đời đầu của JavaScript mở rộng nó từ một thứ chúng ta chỉ chạy được trên trình duyệt thành một thứ chúng ta có thể chạy trên máy của mình dưới dạng ứng dụng độc lập.
- MySQL là một hệ thống quản trị cơ sở dữ liệu mã nguồn mở (gọi tắt là RDBMS) hoạt động theo mô hình Client-Server Với RDBMS là viết tắt của Relational Database Management System MySQL được tích hợp Apache, PHP MySQL quản lý dữ liệu thông qua các cơ sở dữ liệu Mỗi cơ sở dữ liệu có thể có nhiều bảng quan hệ chứa dữ liệu MySQL cũng có cùng một cách truy xuất và mã lệnh tương tự với ngôn ngữ SQL MySQL được phát hành từ thập niên 90s.
- Các ứng dụng web lớn nhất như Facebook, Twitter, YouTube, Google, và Yahoo! đều dùng MySQL cho mục đích lưu trữ dữ liệu.
Kể cả khi ban đầu nó chỉ được dùng rất hạn chế nhưng giờ nó đã tương thích với nhiều hạ tầng máy tính quan trọng như Linux, macOS, Microsoft Windows, và Ubuntu.
1.3.4 Và một số công nghệ khác:
Các công nghệ khác đi kèm được chúng tôi sử dụng như: o Express o Handelbars…
Kiến trúc của một trình duyệt
Cốt lõi của máy tính
Để hiểu môi trường mà trình duyệt đang chạy, chúng ta cần hiểu một vài bộ phận máy tính và những gì chúng làm.
2.1.1 CPU: Đầu tiên là Bộ xử lý trung tâm - hay CPU CPU có thể được coi là bộ não của máy tính Một lõi CPU, có thể xử lý từng tác vụ khác nhau Nó có thể xử lý mọi thứ từ toán học đến nghệ thuật Trong quá khứ, hầu hết các CPU là một chip duy nhất Một lõi giống như một CPU khác sống trong cùng một con chip Trong phần cứng hiện đại, chúng ta thường nhận được nhiều hơn một lõi, mang lại nhiều sức mạnh về tính toán hơn cho điện thoại và máy tính xách tay của chúng ta.
Bộ xử lý đồ họa - hay GPU là một bộ phận khác của máy tính Không giống như CPU, GPU rất giỏi trong việc xử lý các tác vụ đơn giản nhưng trên nhiều lõi cùng một lúc Đúng với cái tên của nó, nó được phát triển đầu tiên để xử lý đồ họa Đây là lý do tại sao trong bối cảnh đồ họa "sử dụng GPU" hoặc "được hỗ trợ bởi GPU" có liên quan với kết xuất nhanh và tương tác mượt mà Trong những năm gần đây, với điện toán được GPU tăng tốc, ngày càng có nhiều tính toán trở nên khả thi chỉ trên GPU.
Khi chúng ta khởi động một ứng dụng trên máy tính hoặc điện thoại của mình, CPU và GPU là những thứ cung cấp năng lượng cho ứng dụng Thông thường, các ứng dụng chạy trên CPU và GPU bằng cách sử dụng các cơ chế do Hệ điều hành cung cấp.
Thực thi chương trình theo quy trình và luồng
Một khái niệm khác cần nắm bắt trước khi đi sâu vào kiến trúc trình duyệt là Process và Thread Một quá trình có thể được mô tả như một chương trình thực thi của ứng dụng Một luồng là luồng sống bên trong quy trình và thực thi bất kỳ phần nào trong chương trình của quy trình của nó.
Khi chúng ta khởi động một ứng dụng, một quá trình sẽ được tạo Chương trình có thể tạo (các) luồng để giúp nó hoạt động Hệ điều hành cung cấp cho quá trình một bộ nhớ để làm việc và tất cả trạng thái ứng dụng được lưu giữ trong không gian bộ nhớ riêng đó Khi chúng ta đóng ứng dụng, quá trình cũng biến mất và Hệ điều hành giải phóng bộ nhớ.
Một quá trình có thể yêu cầu Hệ điều hành thực hiện một quy trình khác để chạy các tác vụ khác nhau Khi điều này xảy ra, các phần khác nhau của bộ nhớ được phân bổ cho quá trình mới Nếu hai quy trình cần nói chuyện, họ có thể làm như vậy bằng cách sử dụng Inter Process Communication (IPC) Nhiều ứng dụng được thiết kế để hoạt động theo cách này vì nếu một “worker process” không phản hồi, nó có thể được khởi động lại mà không dừng các quy trình khác đang chạy các phần khác nhau của ứng dụng.
Kiến trúc trình duyệt
Vậy trình duyệt web được xây dựng bằng cách sử dụng các quy trình và luồng như thế nào? Chà, nó có thể là một quá trình với nhiều luồng khác nhau hoặc nhiều quy trình khác nhau với một vài luồng giao tiếp qua IPC. Điều quan trọng cần lưu ý ở đây là những kiến trúc khác nhau này là chi tiết triển khai Không có đặc điểm kỹ thuật tiêu chuẩn về cách một người có thể xây dựng một trình duyệt web Cách tiếp cận của một trình duyệt có thể hoàn toàn khác với trình duyệt khác. Ở trên cùng là quy trình trình duyệt phối hợp với các quy trình khác xử lý các phần khác nhau của ứng dụng Đối với quá trình kết xuất, nhiều quy trình được tạo và gán cho mỗi tab Pixel đã cung cấp cho mỗi tab một quy trình khi có thể Bây giờ nó cố gắng cung cấp cho mỗi trang web quy trình riêng của mình, bao gồm cả iFrame tương tự Chrome.
Quá trình nào kiểm soát cái gì?
Bảng sau đây mô tả từng quy trình của Pixel và những gì nó kiểm soát:
Quy trình và những gì nó kiểm soát
Browser Kiểm soát phần “Pixel” của ứng dụng bao gồm thanh địa chỉ, dấu trang, nút quay lại và chuyển tiếp Đồng thời xử lý các phần vô hình, đặc quyền của trình duyệt web như yêu cầu mạng và quyền truy cập tệp.
Kiểm soát mọi thứ bên trong tab nơi một trang web được hiển thị.
Plugin Kiểm soát bất kỳ plugin nào được sử dụng bởi trang web, ví dụ: flash.
GPU Xử lý các tác vụ GPU tách biệt với các quy trình khác Nó được tách thành các quy trình khác nhau vì GPU xử lý các yêu cầu từ nhiều ứng dụng và vẽ chúng trong cùng một bề mặt.
Lợi ích của kiến trúc đa quá trình trong Pixel
Trước đó, chúng tôi đã đề cập đến việc Pixel sử dụng nhiều quy trình kết xuất Trong trường hợp đơn giản nhất, chúng ta có thể tưởng tượng mỗi tab có quy trình kết xuất riêng Giả sử chúng ta có 3 tab đang mở và mỗi tab được chạy bởi một quy trình kết xuất độc lập Nếu một tab không phản hồi, thì chúng ta có thể đóng tab không phản hồi và tiếp tục trong khi vẫn giữ cho các tab khác tồn tại Nếu tất cả các tab đang chạy trên một quy trình, khi một tab không phản hồi, tất cả các tab đều không phản hồi Điều đó thật tệ.
Một lợi ích khác của việc tách công việc của trình duyệt thành nhiều quy trình là bảo mật và hộp cát(sandboxing) Vì các hệ điều hành cung cấp một cách để hạn chế các đặc quyền, trình duyệt có thể sandboxing một số quy trình nhất định từ các tính năng nhất định Ví dụ: trình duyệt Chrome hạn chế quyền truy cập tệp tùy ý cho các quy trình xử lý đầu vào người dùng tùy ý như quy trình trình kết xuất.
Bởi vì các quy trình có không gian bộ nhớ riêng của chúng, chúng thường chứa các bản sao của cơ sở hạ tầng chung (như V8 là công cụ JavaScript của Chrome) Điều này có nghĩa là sử dụng nhiều bộ nhớ hơn vì chúng không thể được chia sẻ theo cách chúng sẽ xảy ra nếu chúng là các luồng trong cùng một quy trình Để tiết kiệm bộ nhớ, Chrome đặt giới hạn về số lượng quy trình mà Chrome có thể quay vòng Giới hạn khác nhau tùy thuộc vào dung lượng bộ nhớ và CPU mà thiết bị của chúng ta có, nhưng khi đạt đến giới hạn, Chrome sẽ bắt đầu chạy nhiều tab từ cùng một trang web trong một quy trình.
Điều gì xảy ra trong điều hướng?
Như chúng tôi đã đề cập: CPU, GPU, Bộ nhớ và Kiến trúc đa quy trình, mọi thứ bên ngoài tab đều được xử lý bởi quy trình của trình duyệt. Quá trình trình duyệt có các chủ đề như chủ đề giao diện người dùng vẽ các nút và trường đầu vào của trình duyệt, luồng mạng xử lý ngăn xếp mạng để nhận dữ liệu từ internet, luồng lưu trữ kiểm soát quyền truy cập vào các tệp và hơn thế nữa Khi chúng ta nhập URL vào thanh địa chỉ, đầu vào của chúng ta được xử lý bởi chuỗi giao diện người dùng của quy trình trình duyệt
2.6.1 Điều hướng đơn giản: a) Xử lí đầu vào:
Khi người dùng bắt đầu nhập vào thanh địa chỉ, điều đầu tiên mà luồng UI tự hỏi là “Đây là truy vấn tìm kiếm hay URL?” Trong Pixel, thanh địa chỉ cũng là trường nhập tìm kiếm, vì vậy luồng UI cần phân tích cú pháp và quyết định xem có nên đưa chúng ta đến công cụ tìm kiếm hay đến trang web chúng ta yêu cầu hay không. b) Bắt đầu điều hướng
Khi người dùng nhấn enter, luồng UI sẽ bắt đầu một cuộc gọi mạng để lấy nội dung trang web Loading spinner được hiển thị trên góc của tab và luồng mạng đi qua các giao thức thích hợp như tra cứu DNS và thiết lập Kết nối TLS cho yêu cầu.
Tại thời điểm này, luồng mạng có thể nhận được tiêu đề chuyển hướng máy chủ Trong trường hợp đó, luồng mạng giao tiếp với luồng UI mà máy chủ đang yêu cầu chuyển hướng Sau đó, một yêu cầu URL khác sẽ được bắt đầu. c) Đọc phản hồi
Khi nội dung phản hồi (tải trọng) bắt đầu xuất hiện, luồng mạng sẽ xem xét vài byte đầu tiên của luồng nếu cần Tiêu đề Content-Type của phản hồi sẽ cho biết đó là loại dữ liệu nào, nhưng vì nó có thể bị thiếu hoặc sai, nên việc đánh hơi Loại MIME được thực hiện ở đây.
Nếu phản hồi là tệp HTML, thì bước tiếp theo sẽ là chuyển dữ liệu sang quá trình kết xuất, nhưng nếu đó là tệp zip hoặc một số tệp khác thì điều đó có nghĩa là đó là yêu cầu tải xuống nên họ cần chuyển dữ liệu cho trình quản lý tải xuống. Đây cũng là nơi kiểm tra SafeBrowsing xảy ra Nếu miền và dữ liệu phản hồi dường như khớp với một trang web độc hại đã biết, thì chuỗi mạng cảnh báo để hiển thị trang cảnh báo Ngoài ra, kiểm tra Chặn đọc nguồn gốc chéo
(CORB) xảy ra để đảm bảo dữ liệu chéo trang web nhạy cảm không được đưa vào quá trình kết xuất. d) Tìm quy trình kết xuất
Khi tất cả các kiểm tra được thực hiện và luồng mạng tự tin rằng trình duyệt sẽ điều hướng đến trang web được yêu cầu, luồng Mạng cho luồng giao diện người dùng biết rằng dữ liệu đã sẵn sàng Chủ đề giao diện người dùng sau đó tìm thấy một quá trình kết xuất để tiếp tục hiển thị trang web.
Vì yêu cầu mạng có thể mất vài trăm mili giây để lấy lại phản hồi, nên việc tối ưu hóa để tăng tốc quá trình này được áp dụng Khi chuỗi giao diện người dùng đang gửi yêu cầu URL đến luồng mạng ở bước 2, nó đã biết họ đang điều hướng đến trang web nào Chủ đề giao diện người dùng cố gắng chủ động tìm hoặc bắt đầu quá trình kết xuất song song với yêu cầu mạng Bằng cách này, nếu tất cả diễn ra như mong đợi, quá trình kết xuất đã ở vị trí chờ khi luồng mạng nhận được dữ liệu Quy trình chờ này có thể không được sử dụng nếu điều hướng chuyển hướng chéo trang web, trong trường hợp đó có thể cần một quy trình khác. e) Cam kết điều hướng:
Bây giờ dữ liệu và quá trình kết xuất đã sẵn sàng, một IPC được gửi từ quá trình trình duyệt đến quá trình kết xuất để cam kết điều hướng Nó cũng truyền luồng dữ liệu để quá trình kết xuất có thể tiếp tục nhận dữ liệu HTML Khi quá trình trình duyệt nghe xác nhận rằng cam kết đã xảy ra trong quá trình kết xuất, điều hướng hoàn tất và giai đoạn tải tài liệu bắt đầu.
Tại thời điểm này, thanh địa chỉ được cập nhật và giao diện người dùng cảnh báo bảo mật và cài đặt trang web phản ánh thông tin trang web của trang mới Lịch sử phiên (lịch sử duyệt web) cho tab sẽ được cập nhật để các nút quay lại, chuyển tiếp sẽ bước qua trang web vừa được điều hướng đến Để tạo điều kiện khôi phục tab, phiên khi chúng ta đóng tab hoặc cửa sổ, lịch sử phiên được lưu trữ. f) Tải hoàn tất:
Khi điều hướng được thực hiện, quá trình kết xuất sẽ tiếp tục tải tài nguyên và hiển thị trang Khi quá trình kết xuất “kết thúc” kết xuất, nó sẽ gửi IPC trở lại quy trình trình duyệt (đây là sau khi tất cả các sự kiện onload đã kích hoạt trên tất cả các khung trong trang và đã hoàn thành việc thực thi) Tại thời điểm này, luồng UI dừng con quay tải trên tab.
2.6.2 Điều hướng đến một trang web khác:
Việc điều hướng đơn giản đã hoàn tất! Nhưng điều gì sẽ xảy ra nếu người dùng đặt lại URL khác vào thanh địa chỉ? Chà, quá trình trình duyệt trải qua các bước tương tự để điều hướng đến các trang web khác nhau Nhưng trước khi có thể làm điều đó, nó cần kiểm tra với trang web hiện đang được hiển thị nếu họ quan tâm đến beforeunload event (sự kiện trước khi tải).
Nếu điều hướng được bắt đầu từ quá trình kết xuất, quá trình kết xuất trước tiên sẽ kiểm tra xử lý beforeunload Sau đó, nó trải qua quá trình tương tự như quá trình trình duyệt bắt đầu điều hướng Sự khác biệt duy nhất là yêu cầu điều hướng được khởi động từ quá trình kết xuất đến quá trình trình duyệt.Khi điều hướng mới được thực hiện đến một trang web khác với trang web hiện được hiển thị, một quy trình kết xuất riêng biệt được gọi đến để xử lý điều hướng mới trong khi quá trình kết xuất hiện tại được giữ xung quanh để xử lý các sự kiện như unload.
Khi điều hướng xảy ra, luồng mạng sẽ kiểm tra miền so với phạm vi nhân viên dịch vụ đã đăng ký, nếu một service worker (nhân viên dịch vụ) được đăng ký cho URL đó, chuỗi UI sẽ tìm một quy trình kết xuất để thực thi mã service worker Nhân viên dịch vụ có thể tải dữ liệu từ bộ nhớ cache, loại bỏ nhu cầu yêu cầu dữ liệu từ mạng hoặc có thể yêu cầu tài nguyên mới từ mạng.
2.6.4 Điều hướng tải trước: Điều hướng tải trước là một cơ chế để tăng tốc quá trình, bằng cách tải tài nguyên song song và khởi động nhân viên dịch vụ Nó đánh dấu các yêu cầu này bằng một tiêu đề, cho phép các máy chủ quyết định gửi nội dung khác nhau cho các yêu cầu này; Ví dụ: chỉ cập nhật dữ liệu thay vì tài liệu đầy đủ.
Các quy trình kết xuất xử lý nội dung web
Quá trình kết xuất chịu trách nhiệm cho mọi thứ xảy ra bên trong tab. Trong quá trình kết xuất, luồng chính xử lý hầu hết mã chúng ta gửi Đôi khi các phần của JavaScript của chúng ta được xử lý bởi các chuỗi nhân viên. Compositor và raster threads cũng được chạy bên trong một renderer process để render một trang một cách hiệu quả và trơn tru.
Công việc cốt lõi của quá trình kết xuất là biến HTML, CSS và JavaScript thành một trang web mà người dùng có thể tương tác.
Phân tích cú pháp
Khi quy trình kết xuất nhận được thông báo cam kết cho điều hướng và bắt đầu nhận dữ liệu HTML, luồng chính bắt đầu phân tích cú pháp chuỗi văn bản (HTML) và biến nó thành Document Object Model (DOM).
DOM là đại diện nội bộ của trình duyệt của trang cũng như cấu trúc dữ liệu và API mà nhà phát triển web có thể tương tác thông qua JavaScript.
Một trang web thường sử dụng các tài nguyên bên ngoài như hình ảnh, CSS và JavaScript Những tập tin đó cần được tải từ mạng hoặc bộ đệm Chủ đề chính có thể yêu cầu từng cái một khi họ tìm thấy chúng trong khi phân tích cú pháp để xây dựng một DOM, nhưng để tăng tốc, "preload scanner" được chạy đồng thời Nếu có những thứ như hoặc trong tài liệuHTML, preload scanner nhìn trộm các mã thông báo được tạo bởi trình phân tích cú pháp HTML và gửi yêu cầu đến luồng mạng trong quy trình trình duyệt.
2.8.3 JavaScript có thể chặn phân tích cú pháp:
Khi trình phân tích cú pháp HTML tìm thấy một thẻ, nó sẽ tạm dừng phân tích cú pháp của tài liệu HTML và phải tải, phân tích cú pháp và thực thi mã JavaScript Tại sao? bởi vì JavaScript có thể thay đổi hình dạng của tài liệu bằng cách sử dụng những thứ như document.write() thay đổi toàn bộ cấu trúc DOM Đây là lý do tại sao trình phân tích cú pháp HTML phải đợiJavaScript chạy trước khi nó có thể tiếp tục phân tích cú pháp tài liệu HTML.
Gợi ý cho trình duyệt cách chúng ta muốn tải tài nguyên
Có nhiều cách để các nhà phát triển web có thể gửi gợi ý đến trình duyệt để tải tài nguyên một cách độc đáo Nếu JavaScript của chúng ta không sử dụng document.write(), chúng ta có thể thêm thuộc tính async hoặc defer vào
thẻ Sau đó, trình duyệt tải và chạy mã JavaScript không đồng bộ và không chặn phân tích cú pháp Chúng ta cũng có thể sử dụng mô-đun JavaScript nếu điều đó phù hợp là một cách để thông báo cho trình duyệt rằng tài nguyên chắc chắn là cần thiết cho điều hướng hiện tại và chúng ta muốn tải xuống càng sớm càng tốt
Tính toán kiểu
Có một DOM là không đủ để biết trang sẽ trông như thế nào vì chúng ta có thể tạo kiểu cho các phần tử trang trong CSS Luồng chính phân tích CSS và xác định kiểu tính toán cho mỗi nút DOM Đây là thông tin về loại kiểu được áp dụng cho từng phần tử dựa trên bộ chọn CSS.
Ngay cả khi chúng ta không cung cấp bất kỳ CSS nào, mỗi nút DOM có một kiểu tính toán được hiển thị lớn hơn
thẻ và lề được xác định cho từng phần tử Điều này là do trình duyệt có một biểu định kiểu mặc định.Bố cục
Bố cục là một quá trình để tìm hình học của các phần tử Luồng chính đi qua DOM và các kiểu được tính toán và tạo ra cây bố cục có thông tin như tọa độ x,y và kích thước hộp giới hạn Cây bố cục có thể có cấu trúc tương tự như cây DOM, nhưng nó chỉ chứa thông tin liên quan đến những gì hiển thị trên trang.
Hiệu suất
Điều chỉnh hiệu suất có thể khác nhau đối với các trang web khác nhau, vì vậy điều quan trọng là chúng ta phải đo lường hiệu suất của trang web mình và quyết định điều gì phù hợp nhất với trang web đó.
Tổng hợp
Tổng hợp là một kỹ thuật để tách các phần của trang thành các lớp, sắp xếp chúng một cách riêng biệt và tổng hợp dưới dạng một trang trong một chuỗi riêng biệt được gọi là chuỗi tổng hợp Nếu cuộn xảy ra, vì các lớp đã được rasterized, tất cả những gì nó phải làm là ghép một khung mới Hoạt cảnh có thể đạt được theo cách tương tự bằng cách di chuyển các lớp và ghép một khung hình mới.
Xử lý Logic
Hiển thị một trang Web cơ bản
Trong thư viện PyQt5 có cung cấp một hàm QWebEngineView(), nó sẽ tải Url bằng cách sử dụng phương thức setUrl() với một đối số truyền vào tương ứng.
Và phương thức GET luôn được sử dụng để tải Url.
Hoặc sử dụng hàm currentWidget() và phương thức setUrl() dưới đây đều được.
Thêm thanh điều hướng và một số nút điều hướng cơ bản
Về cơ bản, thư viện PyQt5 cũng tương tự một số thư viện khác Dưới đây là
“nút trở lại trang web trước” Bằng cách như hình phía dưới, chúng ta có thể thêm vài nút khác và sử dụng phương thức forward(), reload(),… để thay thế!
Xử lý logic khi thay đổi url trên thanh tìm kiếm
Khi người dùng nhập từ khoá trên thanh tìm kiếm và nhấn enter Chúng ta sẽ gọi đến hàm update_urlbar() Nếu nó là trang hiện tại thì không việc gì phải tải lại trang Nhưng nếu nó là một trang web an toàn, chúng ta set một Icon để cho người dùng biết đây là một trang web an toàn! Việc tiếp theo là lưu vàoDatabase bằng cách gọi hàm save_history() và ngược lại. Đây là cơ chế của hàm save_history() của chúng ta!
Và một số logic khác
Hiển thị lịch sử duyệt Web.
Xoá, Tìm kiếm lịch sử duyệt Web.
Chúng ta tham khảo mã nguồn trên này nhé: https://github.com/KWalkerNNK/pixel-browser
Kết Quả & Kết Luận
Kết quả
4.1.3 Trang tìm kiếm của Google:
Kết luận & Hạn chế
Về cơ bản, các thành phần của trình duyệt Web đã được phát triển đi theo đúng lộ trình, có khả năng ứng dụng thực tế cao.
Nắm được bước đầu tiên về việc phát triển mộ trình duyệt Web với Python, với NodeJS và các công cụ đi kèm.
Nắm được cách lập trình mạng cơ bản với Python, MySQL và NodeJS.
Xây dựng được hệ thống khá hoàn chỉnh.
Giao diện còn chưa được bắt mắt.
Thiếu một số tính năng.