fix: MPS-24 Phase 2.8e — form.action DOM-clobbered by <input name=action>
With 2.8d live the operator's Network panel proved the proxy-proof
ajax=1 signal works (real fetch to /tags -> 200, 0.7kB JSON) but also
showed 4 requests to a URL literally named [object HTMLInputElement],
with a CORRECT payload (action=delete, tag_slug=..., ajax=1).
Cause: every tag form contains <input type=hidden name=action>. A
named form control clobbers the built-in HTMLFormElement.action
property (DOM clobbering), so fetch(form.action) fetched that <input>
element -> 'String([object HTMLInputElement])' -> resolved to the shop
page (200 HTML, 25.9kB) -> reportFailure, no DOM change ('closer but
nothing changes on screen').
Fix: read form.getAttribute('action') (content attribute, never
clobbered) in submitForm + doReorder; build the programmatic toggle
form with setAttribute('action', ...) instead of form.action =.
No bare form.action reads remain. product_tags.js unaffected (posts
to data-product-tags-url). node --check clean; JS-only defect fix,
no Python/template/test impact.
This closes the chain: 2.8c stale cache -> 2.8d proxy-stripped
X-Requested-With -> 2.8e clobbered form.action. Docs: mps-24.md
Phase 2.8e, CLAUDE.md DOM-clobbering note.
This commit is contained in:
parent
8e31124ca8
commit
7836035d1a
3 changed files with 41 additions and 4 deletions
|
|
@ -363,6 +363,25 @@ Tests (`test_functional.py::TestProductTagsSpa`):
|
|||
Deferred (occasional click, not the hot path): AJAX-ifying the
|
||||
"Suggest categories" link — still a full navigation by design.
|
||||
|
||||
**Phase 2.8e — the LAST link: `form.action` DOM-clobbered** (shipped
|
||||
2026-05-16): with 2.8d live, the operator's Network panel showed the
|
||||
proxy-proof `ajax=1` working (a real `fetch` to `tags` → 200, 0.7 kB
|
||||
JSON) — but also four requests to a URL literally named
|
||||
`[object HTMLInputElement]`, and the Payload tab confirmed the body
|
||||
was correct (`action=delete`, `tag_slug=…`, `ajax=1`). Cause: every
|
||||
tag form contains `<input type="hidden" name="action">`. A named form
|
||||
control **clobbers the built-in `HTMLFormElement.action` property**
|
||||
(DOM clobbering / named-property override), so `fetch(form.action)`
|
||||
fetched that `<input>` element — coerced to the string
|
||||
`"[object HTMLInputElement]"` → resolved against the shop, returned
|
||||
the 25.9 kB shop page (200, non-JSON) → `reportFailure` (no DOM
|
||||
change: "closer but nothing changes"). Fix: read
|
||||
`form.getAttribute("action")` (content attribute, never clobbered),
|
||||
never `form.action`; build programmatic forms with
|
||||
`setAttribute("action", …)`. tag_bulk.js: submitForm, doReorder,
|
||||
swapToggleForm. (No browser test harness exists; guarded via
|
||||
CLAUDE.md note + the `ajax=1` server tests from 2.8d.)
|
||||
|
||||
**Phase 2.8d — the OTHER root cause: proxy strips X-Requested-With**
|
||||
(shipped 2026-05-16): even after 2.8c (fresh JS confirmed loading,
|
||||
`tag_bulk.js?v=<hash>` 200 in the operator's Network panel),
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue