typeform 不支持直接用 嵌入,因 x-frame-options 或 csp 策略拦截导致白屏;必须使用官方 embed.js 脚本,配置域名白名单、启用响应式与自动高度,并正确监听 submit 事件。

为什么直接用 <iframe></iframe> 嵌入 Typeform 会白屏或报错
Typeform 官方明确不推荐用纯 <iframe src="https://..."></iframe> 方式嵌入,尤其在现代浏览器(Chrome 120+、Safari 17+)中,会因 X-Frame-Options: DENY 或 Content-Security-Policy: frame-ancestors 'none' 被拦截,表现为 iframe 空白、控制台报 Refused to display 'https://...' in a frame。
正确路径是使用 Typeform 提供的官方嵌入脚本,它会动态创建 iframe 并绕过部分策略限制,同时支持响应式和事件监听。
- 必须从 Typeform 后台「Share」→「Embed」页面复制完整代码块(含
<script></script>和容器<div>),不能只取 <code>src - 确保你的域名已添加到 Typeform 后台的「Allowed domains」白名单(免费版仅支持 1 个域名,含
localhost) - 若本地开发用
file://协议打开index.html,必然失败——Typeform 不支持 file 协议,必须通过http://localhost:8080类服务运行 - 在 Typeform 后台「Settings」→「Embed」中开启
Responsive embed和Auto-resize height - 嵌入 HTML 中的容器
<div> 必须有唯一 <code>id(如id="typeform-widget"),且不能设height内联样式 - 给容器加最小宽度保护:
<div id="typeform-widget" style="min-width: 300px; width: 100%;"></div>
- 如果页面本身有 CSS 重置(如
box-sizing: border-box全局设置),需确认未意外影响该容器的 padding/margin 计算 - 官方脚本必须放在
底部,或用defer属性:<script defer src="https://embed.typeform.com/next/embed.js"></script>
- 调用
typeformEmbed.makeWidget()必须等脚本完全加载,推荐用window.addEventListener('typeformEmbedLoaded', ...)监听,而非DOMContentLoaded - 不要在多个地方重复调用
makeWidget();每次调用都会新建一个实例,旧实例不会自动销毁,导致内存泄漏和事件重复绑定 - 如果表单 URL 含中文或特殊字符,务必先
encodeURIComponent(),否则初始化时静默失败 - 初始化时传入
onSubmit回调是最简方式:typeformEmbed.makeWidget('#typeform-widget', { url: 'https://example.typeform.com/to/abc123', onSubmit: () => { console.log('用户已提交'); } }); - 若需更细粒度控制(如获取用户邮箱),要用
onReady+widget.on('submit'),注意 widget 实例必须保存为变量,否则回调里拿不到上下文 - 避免在
onSubmit里直接调用window.location.href = '...'—— Typeform 提交后自身有短暂动画,立即跳转会中断;建议加setTimeout(..., 300)或监听thankyou事件 - 如果页面启用了 CSP(Content-Security-Policy),需确保
script-src包含'unsafe-inline'或使用 nonce,否则内联事件监听器会被拒绝
如何让 Typeform 表单在 index.html 中自适应宽度和高度
Typeform 默认嵌入容器是固定高(如 500px),在移动端常被截断或留大片空白。靠 CSS 强制拉伸会导致内容模糊或滚动异常。
真正可靠的方案是启用其内置的响应式 + 自动高度调整:
typeformEmbed.makeWidget() 初始化失败的常见原因
当你手动调用 JS API(比如为了延迟加载、条件触发或监听提交事件),最常卡在 typeformEmbed is not defined 或初始化无反应。
核心问题不是代码写错,而是加载时序和作用域:
如何捕获用户提交成功事件并跳转或弹窗
Typeform 提供了 submit 事件,但默认不暴露给全局作用域,需通过 onReady 后绑定:
localhost 是否被允许,比反复改 CSS 有效得多。











