表单新增蜜罐反垃圾字段;修复 CookieConsent 的 react-hooks/set-state-in-effect lint 报错

This commit is contained in:
2026-08-07 14:49:29 +08:00
parent 3f05bd16e1
commit 1abadd04b8
2 changed files with 15 additions and 0 deletions
+13
View File
@@ -8,6 +8,7 @@ const API_BASE_URL =
export default function LeadForm({ value }: { value: FormBlockValue }) {
const [values, setValues] = useState<Record<string, string>>({});
const [website, setWebsite] = useState(""); // 蜂蜜陷阱字段,正常用户不可见,只有机器人会填写
const [status, setStatus] = useState<"idle" | "submitting" | "done" | "error">(
"idle",
);
@@ -28,6 +29,7 @@ export default function LeadForm({ value }: { value: FormBlockValue }) {
form_id: form!.id,
data: values,
source_url: typeof window !== "undefined" ? window.location.href : "",
website,
}),
});
if (!res.ok) throw new Error("submit failed");
@@ -93,6 +95,17 @@ export default function LeadForm({ value }: { value: FormBlockValue }) {
)}
</div>
))}
{/* 蜂蜜陷阱字段:离屏幕定位而非 display:none,避免部分机器人检测到隐藏属性后跳过;无需 tabIndex/aria-hidden 以外的额外依赖 */}
<input
type="text"
name="website"
value={website}
onChange={(e) => setWebsite(e.target.value)}
autoComplete="off"
tabIndex={-1}
aria-hidden="true"
className="absolute left-[-9999px] top-auto h-px w-px overflow-hidden"
/>
<button
type="submit"
disabled={status === "submitting"}
+2
View File
@@ -10,8 +10,10 @@ export default function CookieConsent() {
useEffect(() => {
// 仅在浏览器已明确同意/拒绝前展示,避免每次访问重复弹出。
// localStorage 只能在客户端读取,此处属于“挂载后同步一次性客户端状态”的合理用法。
const consent = window.localStorage.getItem(CONSENT_STORAGE_KEY);
if (!consent) {
// eslint-disable-next-line react-hooks/set-state-in-effect -- 首次挂载后读取 localStorage 决定是否展示横幅,属预期用法
setVisible(true);
}
}, []);