使用演示前需要完成安全验证
详细验证
包含评分、等级和标记的完整结果
自动验证(小组件模式)
widget.js,含接受规则、HTML5 验证和 preventSubmit
编程式 API
ATValid.validate(email, callback) — 无需绑定 DOM 即可验证
集成示例
一个脚本标签,一次 ATValid.init()。将 pk_live_… 替换为来自 app.atvalid.com/apis 的公开密钥(请限制到您的域名)。
纯 HTML — 快速开始
任何网站:粘贴到 </body> 之前。每个 input[type="email"] 都会在失焦时验证。
<!-- Add before </body> -->
<script src="https://www.atvalid.com/widget/v2/widget.js"></script>
<script>
ATValid.init({
publicKey: 'pk_live_your_public_key_here',
preventSubmit: true // block the submit while the email is invalid
});
</script> MutationObserver,因此稍后注入的表单(AJAX、SPA、页面构建器)会被自动检测。不会向该地址发送任何邮件 — 验证在服务器端完成。全部选项、接受规则与提示信息
显示为默认值。messages.sub(v2.1)给出具体原因,而不是笼统的"无效"。
ATValid.init({
publicKey: 'pk_live_your_public_key_here',
selector: 'input[type="email"]', // which inputs to bind
validateOn: 'blur', // 'blur' | 'input'
verifyAfterDelay: 1000, // ms after typing stops (validateOn: 'input')
timeout: 10, // seconds
showFeedback: true, // message under the input
preventSubmit: false, // block submit when blocked/invalid
formValidation: false, // HTML5 setCustomValidity()
blockOnRateLimit: false,
statusAppendTo: null, // CSS selector or element for the feedback
ignoredForms: [], // form names/ids to skip
ignoredInputs: [], // input names/ids to skip
allow: {
states: ['deliverable', 'risky', 'unknown'], // 'undeliverable' is never accepted by default
free: true, // Gmail, Outlook, Yahoo…
role: true, // info@, sales@, admin@…
disposable: false // temp-mail domains
},
messages: {
checking: 'Verifying email...',
valid: 'Valid email address',
invalid: 'This email appears to be invalid',
disposable: 'Disposable email addresses are not allowed',
role: 'Role-based email addresses are not allowed',
free: 'Free email addresses are not allowed',
suggestion: 'Did you mean {suggestion}?',
networkError: 'Could not verify email. Please check your connection.',
rateLimited: 'Too many requests. Please wait a moment.',
noCredits: 'Validation service temporarily unavailable',
error: 'Could not verify email at this time',
// v2.1 — specific reasons (partial overrides are fine)
sub: {
not_found: 'This mailbox does not exist',
mailbox_full: 'This mailbox is full and cannot receive email',
null_mx: 'This domain does not accept email',
no_mx: 'This domain has no mail server',
blacklist: 'This email domain is blacklisted',
parked: 'This domain is parked and does not receive email',
no_reply: 'No-reply addresses cannot be used',
greylist: 'The mail server asked us to try again later',
toxic: 'This email address cannot be accepted',
catch_all: 'We could not confirm this mailbox exists',
smtp_unknown: 'The mail server did not respond',
suspicious: 'This email address looks suspicious'
}
},
onValidate: function (email, result) { console.log(email, result); },
onError: function (email, error) { console.error(email, error.code, error.message); }
}); WordPress — Contact Form 7、WPForms、Gravity Forms、Elementor、Formidable、Ninja Forms
添加到 footer.php 的 </body> 之前,或使用 "Insert Headers and Footers" / "WPCode" 插件(全站页脚)。
<script src="https://www.atvalid.com/widget/v2/widget.js"></script>
<script>
ATValid.init({
publicKey: 'pk_live_your_public_key_here',
selector: [
'.wpcf7-email', // Contact Form 7
'.wpforms-field-email input', // WPForms
'.gfield input[type="email"]', // Gravity Forms
'.elementor-field-type-email input', // Elementor Forms
'.frm_form_field input[type="email"]', // Formidable
'.nf-form-cont input[type="email"]', // Ninja Forms
'input[type="email"]' // anything else
].join(', '),
validateOn: 'blur',
preventSubmit: true,
allow: { disposable: false, role: false }
});
</script> widget.js 排除在合并之外。RD Station — 落地页与弹窗
落地页 → 设置 → "自定义代码 (HTML/JS)" → </body> 之前。RD 表单是动态加载的;小组件会等待它们。
<script src="https://www.atvalid.com/widget/v2/widget.js"></script>
<script>
ATValid.init({
publicKey: 'pk_live_your_public_key_here',
selector: 'input[type="email"], input[name="email"]',
preventSubmit: true,
formValidation: true, // RD's own validation shows our message
allow: { disposable: false }
});
</script> HubSpot — 表单、落地页、弹窗
设置 → 网站 → 页面 → 高级 → "站点页脚 HTML"(或按页面设置)。HubSpot 表单是动态渲染的 — 会被自动检测。
<script src="https://www.atvalid.com/widget/v2/widget.js"></script>
<script>
ATValid.init({
publicKey: 'pk_live_your_public_key_here',
selector: 'input[type="email"], .hs-input[name="email"]',
preventSubmit: true,
allow: { disposable: false }
});
// Optional: re-scan when HubSpot signals a form is ready
window.addEventListener('message', function (e) {
if (e.data && e.data.type === 'hsFormCallback' && e.data.eventName === 'onFormReady') {
ATValid.refresh();
}
});
</script> Mailchimp — 嵌入式订阅表单
粘贴到您网站上 Mailchimp 嵌入代码之后(Mailchimp 托管的落地页不接受自定义 JS)。
<!-- your Mailchimp embed form is above -->
<script src="https://www.atvalid.com/widget/v2/widget.js"></script>
<script>
ATValid.init({
publicKey: 'pk_live_your_public_key_here',
selector: '#mc-embedded-subscribe-form input[type="email"], #mce-EMAIL',
validateOn: 'input', // validate while typing (debounced 1s)
verifyAfterDelay: 1000,
preventSubmit: true,
allow: { disposable: false, role: false }
});
</script> Google Tag Manager — 自定义 HTML 代码
代码类型"自定义 HTML",触发器"所有页面"(或仅含表单的页面)。适用于任何 CMS,无需修改主题。
<script>
(function () {
var s = document.createElement('script');
s.src = 'https://www.atvalid.com/widget/v2/widget.js';
s.async = true;
s.onload = function () {
ATValid.init({
publicKey: 'pk_live_your_public_key_here',
preventSubmit: true,
allow: { disposable: false },
onValidate: function (email, result) {
// push to the dataLayer for GA4 / conversion rules
window.dataLayer = window.dataLayer || [];
window.dataLayer.push({
event: 'atvalid_email_verified',
atv_accepted: result.accepted,
atv_state: result.state,
atv_sub_status: result.subStatus,
atv_score: result.score
});
}
});
};
document.head.appendChild(s);
})();
</script> onValidate 回调会向 dataLayer 推送事件,供 GA4 / 转化规则使用。Webflow、Wix、Shopify、Squarespace — 全站自定义代码
Webflow:项目设置 → 自定义代码 → 页脚。Wix:设置 → 自定义代码 → body 末尾。Shopify:theme.liquid 中 </body> 之前。Squarespace:设置 → 高级 → 代码注入 → 页脚。
<script src="https://www.atvalid.com/widget/v2/widget.js"></script>
<script>
ATValid.init({
publicKey: 'pk_live_your_public_key_here',
// covers Webflow (.w-input), Wix, Shopify (customer/contact forms) and Squarespace
selector: 'input[type="email"], input.w-input[type="email"], input[name="customer[email]"], input[name="contact[email]"]',
preventSubmit: true,
allow: { disposable: false }
});
</script> React / Next.js
加载一次,绑定到您的输入框,卸载时销毁。在 Next.js 中请将组件标记为 'use client'。
import { useEffect } from 'react';
export function ContactForm() {
useEffect(() => {
const script = document.createElement('script');
script.src = 'https://www.atvalid.com/widget/v2/widget.js';
script.async = true;
script.onload = () => {
window.ATValid.init({
publicKey: 'pk_live_your_public_key_here',
selector: '#email-input',
preventSubmit: true,
formValidation: true,
allow: { disposable: false },
onValidate: (email, result) => console.log(email, result.accepted, result.subStatus)
});
};
document.body.appendChild(script);
return () => {
window.ATValid && window.ATValid.destroy();
document.body.removeChild(script);
};
}, []);
return (
<form>
<input id="email-input" type="email" placeholder="Email" />
<button type="submit">Submit</button>
</form>
);
} ATValid.refresh()(或依赖默认开启的 MutationObserver)。Vue 3 / Nuxt
同样的思路,使用 onMounted / onBeforeUnmount。在 Nuxt 中请放在 <ClientOnly> 或客户端组件内。
<script setup>
import { onMounted, onBeforeUnmount } from 'vue';
let script;
onMounted(() => {
script = document.createElement('script');
script.src = 'https://www.atvalid.com/widget/v2/widget.js';
script.async = true;
script.onload = () => window.ATValid.init({
publicKey: 'pk_live_your_public_key_here',
selector: '#email',
preventSubmit: true,
allow: { disposable: false }
});
document.body.appendChild(script);
});
onBeforeUnmount(() => {
window.ATValid && window.ATValid.destroy();
script && script.remove();
});
</script>
<template>
<form><input id="email" type="email" /><button>Submit</button></form>
</template> 回调、DOM 事件与结果对象(v2.1)
使用 onValidate,或在 document 上监听 atv:verified / atv:error。
document.addEventListener('atv:verified', function (e) {
var r = e.detail.result;
// r = {
// valid: true|false, // API-level verdict
// accepted: true|false, // passed your allow rules → decides the submit
// state: 'deliverable'|'risky'|'unknown'|'undeliverable',
// subStatus: 'ok'|'not_found'|'mailbox_full'|'disposable'|'null_mx'|'no_mx'|'typo'|
// 'blacklist'|'parked'|'no_reply'|'greylist'|'catch_all'|'suspicious'|
// 'role_based'|'toxic'|'smtp_unknown'|'risky'|'invalid', (v2.1)
// toxicity: 0..5, // reputation risk (≥3 is never accepted) (v2.1)
// catchAllConfidence: 0..10|null, // evidence the mailbox exists on a catch-all domain (v2.1)
// score: 0..100, grade: 'A'..'F',
// disposable, free, role: booleans,
// suggestion: '[email protected]' | null, // typo fix (clickable in the feedback)
// email: '[email protected]',
// raw: { ...full API response }
// }
if (!e.detail.accepted) console.log('blocked:', r.subStatus);
});
document.addEventListener('atv:error', function (e) {
// e.detail.error: NETWORK_ERROR | TIMEOUT | RATE_LIMITED | NO_CREDITS |
// DOMAIN_BLOCKED | AUTH_ERROR | API_ERROR | PARSE_ERROR | NO_KEY
console.warn(e.detail.email, e.detail.error);
}); | 输入框上的属性 | 取值 | 含义 |
|---|---|---|
data-atv-valid | "true" | "false" | 已通过您的规则(preventSubmit 检查的内容) |
data-atv-state | deliverable | risky | unknown | undeliverable | 推导状态 |
data-atv-bound | "1" | 小组件已绑定到此输入框 |
编程式 API — 无需绑定 DOM
按需验证(例如 XHR 提交前)、重新扫描、清除缓存、销毁。
// Validate a single address (publicKey optional if init() already ran)
ATValid.validate('[email protected]', 'pk_live_your_key', function (result) {
console.log(result.accepted, result.state, result.subStatus, result.score, result.toxicity);
});
ATValid.refresh(); // re-scan the DOM for new email inputs (SPA navigation)
ATValid.clearCache(); // forget the 5-minute in-page cache
ATValid.destroy(); // remove listeners, observer, styles and feedback 样式
小组件仅注入最少的 CSS;您可以在自己的样式表中覆盖任何类。
.atv-input-valid { border-color: #22c55e !important; box-shadow: 0 0 0 3px rgba(34,197,94,.1) !important; }
.atv-input-invalid { border-color: #ef4444 !important; box-shadow: 0 0 0 3px rgba(239,68,68,.1) !important; }
.atv-input-checking { border-color: #9ca3af !important; }
.atv-feedback { font-size: .8125rem; margin-top: .25rem; font-family: inherit; }
.atv-valid { color: #22c55e; }
.atv-invalid { color: #ef4444; }
.atv-checking { color: #9ca3af; }
.atv-suggestion { color: #d97706; cursor: pointer; text-decoration: underline; }
.atv-suggestion:hover { color: #b45309; }