表单新增蜜罐反垃圾字段;修复 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 }) { export default function LeadForm({ value }: { value: FormBlockValue }) {
const [values, setValues] = useState<Record<string, string>>({}); const [values, setValues] = useState<Record<string, string>>({});
const [website, setWebsite] = useState(""); // 蜂蜜陷阱字段,正常用户不可见,只有机器人会填写
const [status, setStatus] = useState<"idle" | "submitting" | "done" | "error">( const [status, setStatus] = useState<"idle" | "submitting" | "done" | "error">(
"idle", "idle",
); );
@@ -28,6 +29,7 @@ export default function LeadForm({ value }: { value: FormBlockValue }) {
form_id: form!.id, form_id: form!.id,
data: values, data: values,
source_url: typeof window !== "undefined" ? window.location.href : "", source_url: typeof window !== "undefined" ? window.location.href : "",
website,
}), }),
}); });
if (!res.ok) throw new Error("submit failed"); if (!res.ok) throw new Error("submit failed");
@@ -93,6 +95,17 @@ export default function LeadForm({ value }: { value: FormBlockValue }) {
)} )}
</div> </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 <button
type="submit" type="submit"
disabled={status === "submitting"} disabled={status === "submitting"}
+2
View File
@@ -10,8 +10,10 @@ export default function CookieConsent() {
useEffect(() => { useEffect(() => {
// 仅在浏览器已明确同意/拒绝前展示,避免每次访问重复弹出。 // 仅在浏览器已明确同意/拒绝前展示,避免每次访问重复弹出。
// localStorage 只能在客户端读取,此处属于“挂载后同步一次性客户端状态”的合理用法。
const consent = window.localStorage.getItem(CONSENT_STORAGE_KEY); const consent = window.localStorage.getItem(CONSENT_STORAGE_KEY);
if (!consent) { if (!consent) {
// eslint-disable-next-line react-hooks/set-state-in-effect -- 首次挂载后读取 localStorage 决定是否展示横幅,属预期用法
setVisible(true); setVisible(true);
} }
}, []); }, []);