DOM/events, fetch, storage và web security boundaries
Browser API có lifecycle, origin và user-agent constraints; CORS không phải authorization và client storage không phù hợp cho secrets.
1. DOM và event propagation
DOM tree và rendering tree khác nhau. Event đi capture → target → bubble; delegation dựa propagation nhưng phải kiểm tra target/composed path khi có shadow DOM. Passive listeners phù hợp scroll/touch; batch layout reads/writes để tránh forced synchronous layout.
capture -> target -> bubble
delegate on stable ancestor; remove listeners when component unmounts
2. Fetch, streams và cancellation
Fetch resolve cả HTTP 4xx/5xx nên phải check response.ok/status. Request/response body là stream một lần; clone hoặc tee có cost. AbortSignal, credentials, cache, mode và CORS policy ảnh hưởng behavior.
- Phân biệt network failure (reject) với HTTP error (resolved response).
- Đặt deadline và abort underlying fetch khi view/request mất lifecycle.
- Không parse body nhiều lần nếu chưa clone, không buffer file lớn vô hạn.
3. Storage và credential exposure
| Storage | Properties | Risk |
|---|---|---|
| Cookie | HttpOnly/Secure/SameSite; browser tự gửi | CSRF nếu state-changing request thiếu defense |
| local/sessionStorage | Origin-scoped, synchronous, JS-readable | XSS đọc token/data; không phải secret vault |
| IndexedDB | Async, transactional, origin-scoped | XSS vẫn chạy trong origin; schema/cleanup cần lifecycle |
4. Same-origin, CORS và injection
Same-origin policy hạn chế script đọc cross-origin; CORS là server opt-in cho browser read, không thay server authorization. CSP/Trusted Types giảm injection surface; output encoding theo context và sanitizer vẫn cần thiết. Không chèn untrusted HTML hoặc dùng innerHTML tùy ý.
- Credentialed CORS cần explicit origin/credentials và Vary.
- CSRF áp dụng khi browser tự gửi credential; XSS có thể thực hiện action trong session.
- Clickjacking, permissions và referrer policy là các browser boundary khác, không gộp thành một “CORS fix”.