It does not work because the payload is encoded in URL.
If you browse to
https://example.com/?foo= <> "
You'll watch the literal characters
<> " in your URL bar, but the browser has requested
. That is, your browser always encodes some characters in the query string in URL, including quotes and angle brackets.
So, if you access
location.href through JS, the payload in your example will be returned as
test% 3C / option% 3E% 3Cimg% 20src = x% 20onerror = alert (1) /% 3E
. This does not produce any HTML tag unless you first decode it with URL.
Note: As far as I know, all modern browsers behave that way, but historically, some implementations have URL decoded values implicitly for the
Location Interface. In these browsers, your attack would have worked.