- Safari và Firefox triển khai mã thay đổi cách kết xuất và hành vi API trên các tên miền cụ thể như TikTok, Netflix, Instagram
- about:compat của Firefox hiển thị các can thiệp theo từng trang và công tắc bật/tắt, đồng thời thực hiện chèn CSS·JavaScript tùy chỉnh và ngụy trang user agent
- WebKit của Safari quản lý việc này dưới dạng quirks, dùng để lách theo từng tên miền cho các vấn đề về video PiP, căn chỉnh hình ảnh, popover và quyền truy cập streaming
- Chrome hầu như không cần tệp ngoại lệ riêng, vì web vốn đã được xây dựng xoay quanh Chrome, còn các trình duyệt khác phải bù lại sự khác biệt
- Các ngoại lệ này không dễ lộ ra trong log hay console, nên lập trình viên cần kiểm tra định kỳ trên Firefox và Safari, đồng thời xác minh xem có xuất hiện trong tệp quirks hay không
Xử lý ngoại lệ theo từng tên miền bên trong trình duyệt
- Safari và Firefox triển khai mã thay đổi cách kết xuất hoặc hành vi API tùy theo tên miền mà người dùng truy cập
- Các trang như TikTok, Netflix, Instagram, SeatGuru là đối tượng của kiểu xử lý theo từng trang này
- Có thể kiểm tra công khai mã nguồn liên quan tại
Quirks.cpp của WebKit và WebCompat interventions của Firefox
- Mã này được đưa vào engine kết xuất của trình duyệt theo cách như “nếu là tên miền cụ thể thì kết xuất khác đi” hoặc “nếu là tên miền cụ thể thì xử lý lời gọi API khác đi”
- Chrome trên thực tế gần như không cần các tệp ngoại lệ kiểu này, cho thấy sự bất đối xứng khi web đã được xây dựng lấy Chrome làm trung tâm
about:compat của Firefox
- Nếu nhập
about:compat vào thanh địa chỉ của Firefox, bạn có thể thấy danh sách can thiệp theo từng trang cùng các công tắc bật/tắt
- Mỗi mục là một chỉnh sửa riêng cho một website cụ thể, và nếu tắt đi bạn có thể thấy trang bị lỗi như thế nào
- WebCompat system của Firefox chèn CSS và JavaScript tùy chỉnh theo từng tên miền cụ thể
- Với những trang nhận diện sai trình duyệt, Firefox sẽ gửi đi chuỗi user agent đã được thay đổi
- Những can thiệp này che đi lỗi để web không trông như bị hỏng, và trong Mozilla Bugzilla còn theo dõi cả báo cáo lỗi lẫn nỗ lực liên hệ với website
quirks của Safari
- Engine WebKit của Safari gọi cách xử lý này là quirks, và
Quirks.cpp được công khai trên GitHub
- Trong mã WebKit có chú thích rằng Facebook, X, Reddit sẽ tạm dừng
<video> bị cuộn ra ngoài màn hình bất kể có đang ở chế độ PiP hay không
- Safari phát hiện
facebook.com, x.com, reddit.com và thay đổi cách xử lý video Picture-in-Picture
- Ngay cả khi mã video của trang bị lỗi, trình duyệt không chờ các công ty đó sửa mà triển khai cách lách cho tất cả người dùng
- Chú thích liên quan đến SeatGuru có câu
FIXME: Remove this quirk if seatguru decides to adjust their site., cho thấy ngoại lệ có thể được gỡ bỏ nếu trang được sửa
- Lịch sử commit cho thấy trong vài tháng gần đây đã có nhiều chỉnh sửa theo từng trang được thêm vào
- Vấn đề ảnh mặt bằng của Zillow không được căn giữa
- Vấn đề TikTok hiển thị thông báo “please upgrade your browser”
- Vấn đề Instagram Reels bị đổi kích thước thất thường khi đang phát
- Vấn đề nút “Episodes and Info” của Netflix đóng popover sai cách
- Vấn đề Twitch tạm dừng video PiP khi chuyển tab
- Vấn đề Amazon Prime Video không cho người dùng Safari xem nội dung
Web lấy Chrome làm trung tâm và sự bất đối xứng
- quirks của WebKit và WebCompat của Firefox không chỉ sửa các trang bị lỗi, mà còn bù lại tình thế trong đó Chrome quyết định tiêu chuẩn của cái gì là “hoạt động được”
- Thông thường, khi Chrome triển khai một tính năng, do sức mạnh thị trường nên lập trình viên sẽ dùng tính năng đó, còn các trình duyệt khác phải triển khai theo hoặc che đi khác biệt bằng ngoại lệ theo từng trang
- Đến lúc Safari và Firefox bắt kịp thì các xử lý ngoại lệ ấy đã được triển khai cho hàng triệu người dùng
- WebKit có cả user agent override khiến Safari trông như Chrome trên trang video của Amazon và nhiều dịch vụ streaming khác
- Những trang này phát hiện có phải Chrome hay không để cung cấp trải nghiệm kém hơn cho trình duyệt khác, nên WebKit đánh lừa danh tính trình duyệt để bảo vệ người dùng Safari
- Hiện tại
Quirks.cpp chứa chuỗi user agent Chrome giả như sau
auto chromeUserAgent = "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/143.0.0.0 Safari/537.36"_s;
- Firefox cũng hoạt động theo cách tương tự, và nhiều can thiệp trong
about:compat là ngụy trang user agent để nói với trang rằng “tôi là Chrome”
- Mozilla wiki cho biết một số trang sẽ “chặn hoàn toàn quyền truy cập, hiển thị thiết kế khác hoặc cung cấp tính năng khác” tùy theo kết quả nhận diện trình duyệt
- Cấu trúc này tạo ra một vòng phản hồi
- Lập trình viên xây dựng theo Chrome vì Chrome có thị phần lớn
- Website hoạt động tốt nhất trên Chrome
- Người dùng gặp lỗi ở trình duyệt khác sẽ đổ lỗi cho trình duyệt chứ không phải cho website
- Người dùng chuyển sang Chrome, và sự thống trị của Chrome càng mạnh hơn
- Lý do Chrome gần như không cần tệp quirks riêng không phải vì Chrome được thiết kế tốt hơn, mà vì web đã được căn chỉnh theo Chrome từ trước
- Trong bối cảnh người dùng trình duyệt dựa trên Chromium vượt quá 80%, lập trình viên sẽ nhắm tới Chrome trước tiên
- Nếu website hoạt động trên Chrome thì sẽ được triển khai, còn nếu hỏng trên Safari hoặc Firefox thì mức độ ưu tiên xử lý sẽ thấp hơn
- Thay vì thêm ngoại lệ, Chrome lại thiết lập nghị trình
- Khi Chrome thay đổi một hành vi nào đó, website sẽ cập nhật theo, còn các trình duyệt khác либо phải theo kịp, либо bị lỗi
Khoảng cách giữa đặc tả và web thực tế
- Các kỹ sư trình duyệt có thể xem đặc tả hiện nay là khá rõ ràng, và cách tiếp cận “living specification” của HTML5 đã giảm bớt hỗn loạn thời IE/Netscape
- Vấn đề là lập trình viên phụ thuộc vào chi tiết triển khai không có trong đặc tả, và nếu các chi tiết đó khác nhau giữa các trình duyệt thì họ lại đổ lỗi cho trình duyệt không tuân thủ
- Khi cách triển khai của Chrome trở thành chuẩn mà mọi người nhắm tới, các hành vi chi tiết ngoài đặc tả của Chrome sẽ trở thành đặc tả trên thực tế
- Hồi thời Internet Explorer những năm 2000 cũng vậy: lập trình viên xây website theo IE khiến trang bị lỗi trên trình duyệt khác, và ưu tiên khi đó là “chạy được trên IE” chứ không phải tuân thủ chuẩn
- Trước đây người ta từng kỳ vọng rằng nếu web tuân thủ chuẩn tốt hơn thì quirks của trình duyệt sẽ biến mất, nhưng trên thực tế quirks không biến mất mà chỉ chuyển sang các trình duyệt không phải Chrome
- Chuẩn được tạo ra để loại bỏ mã riêng cho từng trình duyệt, nhưng sau khi thoát khỏi thời IE, cùng một lỗ hổng lại xuất hiện quanh một trình duyệt khác
- Giờ đây mã riêng cho từng trình duyệt không nằm trong trình duyệt thống trị, mà nằm trong các trình duyệt không thống trị để bù cho một web đã được điều chỉnh theo trình duyệt thống trị
Xử lý ngoại lệ ăn sâu hơn bạn nghĩ
- Kiểu xử lý này không chỉ dừng ở chỉnh sửa hiển thị đơn giản, mà còn thay đổi hành vi mặc định của trình duyệt theo từng tên miền
- Chỉ riêng danh sách của WebKit đã dài tới hàng nghìn dòng, bao gồm hành vi cuộn, xử lý sự kiện chạm, tính toán viewport, và cả xử lý kiểu MIME của ảnh
- Trong chú thích cho tính năng phóng to ảnh sản phẩm Amazon có đoạn sau
When panning on an Amazon product image, we’re either touching on the #magnifierLens element or its previous sibling.
- Safari kiểm tra xem có đang truy cập Amazon hay không, rồi thay đổi cách chuyển đổi sự kiện chạm thành sự kiện chuột cho tính năng phóng to sản phẩm
- Do website của Amazon giả định một hành vi sự kiện cụ thể khác với hành vi mặc định của Safari, nên Safari chỉ cung cấp hành vi đó riêng cho Amazon
- Cả storage access, kết xuất thanh cuộn, hành vi tự động sửa, và xử lý thu phóng cũng có quirks theo từng tên miền
- Mỗi ngoại lệ đều nằm sau một bước kiểm tra tên miền và được biên dịch vào trong tệp thực thi của trình duyệt
Vì sao trình duyệt tự sửa thay vì chờ đợi
- Các nhà cung cấp trình duyệt đôi khi có liên hệ với website có vấn đề để yêu cầu sửa, và trong mã nguồn cũng có những trường liên kết với nỗ lực outreach như vậy
- Nhưng nếu một website phổ biến chạy được trên Chrome mà lại lỗi trên trình duyệt của họ, người dùng sẽ đổ lỗi cho trình duyệt chứ không phải cho website
- So với việc gửi bug cho bên thứ ba rồi chờ vài tuần hoặc vài tháng, việc triển khai một cách lách 5 dòng ngay ngày hôm sau thực tế hơn nhiều đối với trình duyệt
- Thậm chí không phải lúc nào cũng rõ cần liên hệ với ai
- Lập trình viên viết đoạn mã lỗi đó có thể đã rời công ty
- Đội sở hữu endpoint đó có thể không nhận thức mình phải chịu trách nhiệm
- Website có thể đang ở chế độ bảo trì chỉ nhận bản vá bảo mật
- Với trình duyệt, lựa chọn sửa ngay lập tức, âm thầm, để giảm vấn đề cho người dùng là điều đơn giản hơn
- Một kỹ sư WebKit cũng có bài viết về quá trình gỡ quirk của FlightAware
- FlightAware so sánh chuỗi CSS transform matrix, và khi đặc tả CSS thay đổi cách tuần tự hóa giá trị, trình duyệt làm đúng theo đặc tả thì website lại bị lỗi
- Các kỹ sư đã thêm mã theo từng tên miền để kiểm tra
flightaware.com, rồi sau đó liên hệ thành công và FlightAware sửa mã, nên quirk được gỡ bỏ
- Trong vài tháng đó, người dùng Safari vẫn có trải nghiệm bình thường nhờ câu lệnh
if bên trong trình duyệt
Điều lập trình viên cần kiểm tra
- Website của bạn có thể đang nhận xử lý kết xuất đặc biệt mà chính bạn không hề biết
- Những quirk này không xuất hiện trong log lỗi, và console cũng không hiện cảnh báo kiểu “trình duyệt đang lách qua lỗi”
- Các cách lách được thiết kế để hoạt động một cách vô hình
- Các website chỉ kiểm thử xoay quanh Chrome đặc biệt dễ gặp rủi ro này
- Lý do website hoạt động hoàn hảo có thể không phải vì mã tốt, mà vì hành vi của Chrome vô tình trùng khớp với giả định của lập trình viên
- Các trình duyệt khác phải đứng trước lựa chọn: hiển thị website bị lỗi cho người dùng, hoặc thêm nó vào tệp quirks
- Bạn cần mở website trên Firefox và Safari không phải thỉnh thoảng mà là thường xuyên, định kỳ
- Tệp quirks tồn tại vì lập trình viên đã không làm điều đó một cách đều đặn
- Nếu tên miền của bạn có mặt trong tệp quirks, bạn cần kiểm tra phần nào đã bị trình duyệt xử lý lách qua
- Web vẫn tiếp tục hoạt động mà không cần lập trình viên can thiệp, nhưng có thể các kỹ sư của những trình duyệt bạn không dùng đã âm thầm sửa những vấn đề mà bạn không hề biết
1 bình luận
Ý kiến trên Lobste.rs
Đằng sau đống văn LLM này có giấu một câu chuyện thú vị
Có thể bạn không thích văn phong đó, và tôi cũng không nhất thiết muốn tranh cãi về điểm này, nhưng bài viết dở không đồng nghĩa chắc chắn do AI viết. Trước thời AI cũng đã có vô số câu văn tệ rồi
Thật đáng buồn, và tôi ước mình sống trong một thế giới mà Google không chi phối web đến mức này. Giấc mơ về “web” từng tham vọng hơn nhiều và, với cá nhân tôi, cũng truyền cảm hứng hơn nhiều; thật tiếc khi nó đã thành ra như bây giờ
Khối trích dẫn khó đọc. Có thể là vấn đề của dark mode
Dù vậy, việc chia sẻ chi tiết về cách обход vẫn rất hữu ích
Đoạn “Những site này phát hiện có phải Chrome không rồi cung cấp trải nghiệm kém hơn cho các trình duyệt khác. Vì thế, thay vì để người dùng Safari phải chịu khổ, WebKit nói dối về việc nó là trình duyệt nào” có vẻ là chuyện lặp đi lặp lại trong cả ngành này
Các hãng sản xuất máy tính cũng không hiếm khi tung ra firmware ACPI che giấu thông tin với những hệ điều hành không được hỗ trợ, để rồi cuối cùng các hệ điều hành đó phải giả làm Windows để lừa firmware
Tôi không thích việc bài này đọc lên giống văn phong AI
Ngoài những gì bài viết nói, còn có hai vòng lặp phản hồi nữa. Một là vì Chrome thống trị nên dev làm theo chuẩn Chrome, rồi mọi thứ chạy tốt nhất trên Chrome, và nếu phát sinh vấn đề trên trình duyệt khác thì người dùng sẽ đổ lỗi cho trình duyệt chứ không phải site, sau đó chuyển sang Chrome
Vòng còn lại là site bị hỏng trên Firefox nhưng phía vận hành site lại nói rằng trong thống kê họ không thấy người dùng Firefox. Chuyện này vẫn có thể xảy ra ngay cả khi có xử lý đặc biệt kiểu đổi user agent
Nếu tôi nhớ không nhầm thì Opera cổ điển (Presto) là nơi đầu tiên bắt đầu triển khai kiểu lớp tương thích này
Triển khai chính là đặc tả là một vấn đề rất phổ biến trong lĩnh vực này. Ở công ty cũ, chúng tôi dùng một ngôn ngữ workflow có bộ test tuân thủ, với hy vọng sẽ có nhiều implementation xuất hiện và workflow trở nên portable
Vấn đề cốt lõi là động lực kinh tế để tạo ra tính portable hoàn toàn là rất thấp. Người ta luôn muốn thêm tính năng riêng vào implementation của mình để giữ người dùng ở lại với sản phẩm đó
Ngoài ra cũng không có thời gian để làm phần mềm theo kiểu ủy ban, nên ai cũng muốn đi trước và đưa tính năng mới vào trước
Triển khai trở thành đặc tả là vì chúng ta đang sống trong một xã hội loài người
Đây không phải chuyện mới. Các trình duyệt thiểu số từ lâu luôn có các hack dành riêng cho từng site, và trước đây mục tiêu là IE. Phương án khác chỉ là để site hỏng nguyên như vậy
Hàng chục năm trước, dev web làm ra những site chỉ chạy trên IE rồi bảo rằng “muốn dùng site này thì hãy dùng IE”, và bây giờ điều tương tự đang lặp lại với Chrome. Chrome đúng hay sai không quan trọng. Site chỉ chạy trên Chrome, và nếu trình duyệt khác không đảm bảo hành vi kiểu Chrome trên site đó thì người ta sẽ nói “trình duyệt này bị lỗi” rồi chuyển sang Chrome
Tôi thật sự thắc mắc không biết mọi người nghĩ Gecko và WebKit nên để nguyên các site đó bị hỏng vì nguyên tắc, hay là nghĩ rằng tất cả mọi người chỉ nên dùng Chrome và đừng dùng trình duyệt khác nữa. Với hack riêng cho từng site thì chỉ có hai lựa chọn đó thôi
Tôi thấy chuyện Firefox và Safari giả làm Chrome bằng user agent khá buồn cười
Nhưng trong chuỗi user agent của Chrome vẫn còn lưu lại những dấu tích hóa thạch từ thời nó giả làm trình duyệt Mozilla và giả làm trình duyệt của Apple
Chỉ một dòng code này mà chất đầy các tầng địa chất: