☰
允许任意网站iframe嵌入:X-Frame-Options与CSP frame-ancestors配置详解
2026/10/14 6:56:47 网站建设 项目流程

最近我在调一个某跨平台项目,需要在管理后台里直接嵌入另一个业务系统的报表页面。结果 Chrome 控制台毫不留情地甩了一句:Refused to display 'xxx' in a frame because it set 'X-Frame-Options' to 'sameorigin'。页面是白的,业务方在催,我盯着报错一脸懵。后来仔细翻了规范、测了各种浏览器行为才发现,"允许某个网站被任何网站的 iframe 嵌入"这件事,远比在响应头里删掉一行配置要复杂得多。

这篇东西我就从报错根源讲起,把 X-Frame-Options、CSP frame-ancestors 这两种控制策略的来龙去脉、配置方式、踩坑点都捋一遍。主要是给做前端的、管服务器的、以及需要做第三方页面嵌入对接的同行看的,保证拿到就能直接用,也顺便讲清楚每步为什么要这么做。

1. 被拒绝嵌入的本质:谁在拦截你的 iframe

先回到那个报错现场。嵌入方页面 A(比如我的管理后台)通过<iframe src="https://b.example.com/report">想加载目标网站 B(业务系统报表页),浏览器直接拦截了。这里拦截你的不是某个中间设备,也不是对方的业务逻辑,而是目标网站 B 自己下发的 HTTP 响应头。

1.1 响应头是如何"通知"浏览器的

目标网站在收到页面请求后,会在 HTTP 响应里带上一个专门的头部字段。浏览器拿到 HTML 内容之前,先检查这个响应头,一旦发现它声明了"不允许被嵌入",就会放弃渲染页面主体,并在控制台输出拒绝信息。这就是X-Frame-Options(下面简称 XFO)的工作机制。

XFO 一共就三个取值,语义非常直白:

取值含义
DENY任何页面都不能以 iframe 嵌入,同源也不行
SAMEORIGIN只允许同源页面嵌入
ALLOW-FROM https://x.com允许指定来源嵌入(这个值已经被废弃,后面细说)

绝大多数你在网上遇到的"被拒绝嵌入"问题,都是目标站把 XFO 设置成了SAMEORIGIN或DENY。前者最常见,因为很多框架和中间件会默认加这个头,比如某些后端脚手架、安全过滤器,甚至不少 Web 服务器的默认配置。

1.2 为什么要发明这个头:点击劫持那点事

你可能会觉得这功能纯粹是给开发添堵,但它的诞生和一类叫"点击劫持"的攻击直接相关。攻击者把自己的恶意页面嵌在一个透明的 iframe 里,然后诱导用户在不知情的情况下点击页面上的按钮,比如"领取奖励""确认支付",实际点到的却是透明 iframe 里的"确认转账"。如果目标网站允许被任意嵌入,这类攻击要做到很难防御。XFO 就是浏览器层面最简单粗暴的防线:不让嵌,自然就没法劫持点击。

理解了这一层,你就能明白为什么很多安全扫描工具、等保测评都会要求必须配置 XFO 或者 CSP 的 frame-ancestors。所以你在改这个头之前,得先想清楚自己是不是真的要"对所有网站开放嵌入",而不是图省事一刀切。

1.3 同源策略和 XFO 是两套东西

这里经常有人混淆。浏览器的同源策略规定,不同源的 iframe 之间 JS 不能互相读取 DOM、不能共享 localStorage,这是第一道坎。XFO/CSP frame-ancestors 管的是"这个页面允不允许被放进 iframe",这是第二道坎。两道坎是独立的——同源的 iframe 依然可能被 XFO 拦截(比如DENY),异源的 iframe 只要目标源允许也能正常显示,只是里面的 JS 你碰不了。

我见过一个典型的误判:A 项目嵌 B 项目页面前,有人测了网络请求,发现 HTML 都能回来,以为是跨域 JS 问题,折腾半天 Webpack devServer 代理,最后才意识到是响应头直接把页面拒了。所以遇到 iframe 白屏,第一步应该开 DevTools → Network,看目标页面的响应头里有没有 XFO 或 Content-Security-Policy,而不是急着调跨域配置。

2. 两种标准姿势:XFO 和 CSP frame-ancestors 怎么选

真正要动手"允许某个网站被任何网站的 iframe 嵌入"时,摆在你面前的是两条技术路径:旧的 XFO 和新的 CSP 指令frame-ancestors。很多人只知道 XFO,因为它的名字够老、够常见,但如果只靠 XFO 会踩不少坑。

2.1 XFO 的边界条件比你想的多

XFO 看起来就一行配置的事儿,但实测下来有三个容易翻车的点。

端口不同就不算同源。这是最容易被忽略的。http://example.com:8080去嵌http://example.com的页面,即便域名完全一样,只要端口不同,SAMEORIGIN也会拒绝。本地调试时尤其常见:前端跑在 3000 端口,想去嵌后端模板引擎渲染的 8080 页面,结果 XFO 是 SAMEORIGIN,怎么嵌都是白屏。

子域不同更不算同源。admin.example.com嵌www.example.com,XFO SAMEORIGIN 照样拒。同源的定义是协议 + 域名 + 端口三者完全一致,子域属于不同源。这一点在很多企业内网系统里尤其坑,权限系统和主站经常分布在不同的子域下,要做嵌入就得把 XFO 改成ALLOW-FROM或者换 CSP。

ALLOW-FROM 实际上没几个人支持。当年规范里定义过ALLOW-FROM让你指定允许的源,但 Firefox 一直没实现,后来现代浏览器干脆把它废弃了。现在你写了ALLOW-FROM https://x.com,Chrome、Firefox 基本直接忽略,等价于没有保护,页面反而全站可嵌。这个坑相当隐蔽,因为语法是合法的、不会报错,但实际上完全没生效。你用 curl 或者 DevTools 看响应头,会发现它还在,但浏览器根本不按这个值做判断。

2.2 CSP frame-ancestors 才是推荐做法

CSP(Content Security Policy)里有一个专门管 iframe 嵌入的指令叫frame-ancestors,它比 XFO 灵活得多:

Content-Security-Policy: frame-ancestors 'self' https://a.example.com https://b.example.com;

这个指令明确列出了"哪些网站的页面可以把我嵌进去"。注意它的语法和 XFO 完全不同,frame-ancestors的值不以斜杠结尾、不支持路径,只写 scheme + host。具体说:

  • 'self'表示同源可以嵌
  • 可以写多个来源,用空格分隔,不需要逗号
  • 支持通配符,比如https://*.example.com表示该域名下的所有子域都能嵌
  • 写*就表示任何网站都能嵌——这正是你这个需求要的

浏览器在 XFO 和 CSP frame-ancestors 同时存在时,以 CSP 为准。Chrome 和 Firefox 都是这个行为,CSP 会直接覆盖 XFO 的设置。这么做的好处是你不用去删老配置,直接加一个 CSP 头就能覆盖。但 Safari 的行为有点特殊,老版本 Safari(特别是 15 之前的)对 frame-ancestors 的支持不完整,某些版本会忽略它、直接看 XFO。所以稳妥的做法是:两个头都设置,并且让它们的语义保持一致,而不是只依赖其中一个。

2.3 兼容性实测

我拿同一台测试服分别设了四种响应头,用不同浏览器访问嵌有该页面的容器页,结果如下:

目标站响应头ChromeFirefoxSafari
XFO: DENY拒绝拒绝拒绝
XFO: SAMEORIGIN同源可嵌,异源拒绝同源可嵌,异源拒绝同源可嵌,异源拒绝
XFO: ALLOW-FROM https://x.com忽略,等同无保护忽略,等同无保护部分版本不识别,等同无保护
CSP frame-ancestors https://x.com允许 x.com 嵌入允许 x.com 嵌入新版支持,旧版看 XFO
CSP frame-ancestors *全站可嵌全站可嵌新版全站可嵌

这个表建议存一下,做兼容性验证时会有用。我在实际项目中见过因为信了"ALLOW-FROM 能指定白名单"导致线上页面可以任意被嵌的情况,非常麻烦。

3. 允许任意网站嵌入的完整落地步骤

明确了目标——让任何网站都能用 iframe 加载你的页面——接下来的问题是怎么在真实的服务器环境里把这些响应头配上去。我按最常见的几种部署方式分别给配置示例,并提供验证方法。

3.1 静态配置:Nginx、Apache 与中间件

Nginx的环境里,最简单粗暴的方式是在 server 块里加:

server { listen 443 ssl; server_name example.com; # 允许任何网站嵌入 add_header Content-Security-Policy "frame-ancestors *"; add_header X-Frame-Options "ALLOWALL"; ... }

注意ALLOWALL这个值不是一个正式标准取值,但不少老项目在用。严格说它不属于规范的 XFO 合法值,浏览器也不会主动处理它。我把它写在这里仅仅是为了提醒你:网上抄来的ALLOWALL配置其实什么都不干,真正起作用的还是上面的 CSP。如果你有洁癖,可以不写 XFO 这一行,只靠 CSPframe-ancestors *就够。但考虑到 Safari 老版本的行为,建议 XFO 也不要设成DENY/SAMEORIGIN,干脆不设,或者设成一个不会误伤的值。因为一旦设了,CSP 因为各种原因没被识别(比如服务器配置错了)时,XFO 就会变成兜底拦截,页面还是白屏。

Apache环境用 Header 指令:

<IfModule mod_headers.c> Header always set Content-Security-Policy "frame-ancestors *" </IfModule>

always关键字很关键。不加的话,Apache 在 2xx 响应里也会加,但对 3xx 重定向、4xx/5xx 错误页可能不加。iframe 首次加载经常伴随重定向(比如登录态跳转、加尾斜杠),漏掉这个头,重定向链路上如果某个中间响应被浏览器识别为最终响应,就会出问题。

后端代码里设响应头更灵活,也更容易做条件判断。比如 Node.js 的 Express:

app.use((req, res, next) => { // 对特定路径开放嵌入,其他路径保持默认策略 if (req.path.startsWith('/embed/')) { res.setHeader('Content-Security-Policy', "frame-ancestors *"); } else { res.setHeader('Content-Security-Policy', "frame-ancestors 'self'"); } next(); });

Java Servlet 过滤器里这样写:

@Override public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) { HttpServletResponse response = (HttpServletResponse) res; response.setHeader("Content-Security-Policy", "frame-ancestors *"); chain.doFilter(req, res); }

Python Flask 可以直接用after_request钩子:

@app.after_request def add_header(response): response.headers["Content-Security-Policy"] = "frame-ancestors *" return response

我个人建议用后端代码的方式而不是只改 Web 服务器配置,因为你能按路径、按用户角色、按请求参数做细粒度控制。比如/embed/下的页面开放给所有站点,/admin/下的页面只允许同源嵌入,这种逻辑在 Nginx 里写起来很别扭,但在应用层就是几行代码。

3.2 千万别指望 HTML meta 标签

有一种做法我看到不少人试过:在页面<head>里写一个<meta http-equiv="Content-Security-Policy" content="frame-ancestors *">,想着不用改服务器就能搞定。实测结论是:这个写法无效。

frame-ancestors指令有一个特殊限制:它只能通过 HTTP 响应头设置,不能在 HTML 的<meta>元素里设置。这是 CSP 规范明确写的,因为frame-ancestors影响的是"谁在嵌我",是在导航阶段就决定的策略,如果允许 meta 设置,攻击者可以往页面里注入一个 meta 标签就把保护关掉,那这套机制就没有意义了。所以千万别在 meta 上浪费时间。

X-Frame-Options也不能用 meta 设置。它的历史更早,和 meta 的机制完全不兼容。网上传的<meta http-equiv="X-Frame-Options" content="allowall">同样是无效的,浏览器会忽略它。所有想靠 HTML 标签搞定嵌入权限的想法,基本都走不通,必须从响应头下手。

3.3 验证配置到底生没生效

配置完了别急着肉眼判断,用几个命令就能确认:

# 查看响应头 curl -I https://example.com/embed/page # 只看 CSP 和 XFO 相关 curl -sI https://example.com/ | grep -i -E 'content-security|x-frame'

一个正常的、允许任意嵌入的响应,应该至少能看到:

content-security-policy: frame-ancestors *

如果看到的是x-frame-options: SAMEORIGIN而不是 CSP,说明你的配置没生效,或者被框架默认值覆盖了。这里要特别提醒:有些框架会在代码里自动加上安全响应头,你再在配置文件里加一遍,结果可能冲突。我自己就遇到过 Spring Security 默认把 XFO 设成SAMEORIGIN,我在 Nginx 里加了frame-ancestors *,Chrome 按 CSP 覆盖了 XFO,一切正常;但 Safari 老版本认的是 XFO,直接拒了——所以查配置时,两头都要看,两头都要改。

浏览器端的最终验证也很简单:在 A 网站页面里写一个 iframe,src 指向 B 网站的页面,然后刷新 A 站点页面。如果正常显示,说明 B 网站确实允许任何来源嵌入;如果白屏,按 F12 进 Network 面板,看 B 页面那个请求的响应头,对照请求 URL 和响应头里的 CSP 值就能定位问题。

3.4 嵌入之后还有一道跨域坎

响应头搞定了,页面能显示了,不代表你就能在嵌入方网站里随意操作这个 iframe。前面提到过,不同源的两个页面之间,JS 是受限的。嵌入方网站 A 用 JS 去改 iframe 里的 DOM、读内容、监听事件,都会被浏览器拦截,控制台报Blocked a frame with origin ... from accessing a cross-origin frame。这不是你配置的问题,而是浏览器安全模型的设计使然。

如果你确实需要在嵌入方页面和被嵌入页面之间通信,标准做法是window.postMessage。被嵌入页在内部主动往父窗口发消息,父窗口通过message事件接收并处理。这里注意验证消息来源,用event.origin判断是不是你期望的嵌入方站点,避免有人伪造消息。

4. 开放嵌入的安全代价与补救措施

把frame-ancestors设成*意味着任何网站都能把你页面嵌进去,这确实带来了便利,但也把一个熟悉的老对手请回了牌桌:点击劫持。你把自己暴露给了所有恶意站点,他们可以在自己的页面上叠一个透明层,诱导访客点击你的按钮、填你的表单。

4.1 点击劫持为什么在"允许任何嵌入"时特别危险

正常来说,恶意站点想对你实施点击劫持,需要先让你的页面在 iframe 里能正常加载。你禁止嵌入,这个攻击面就完全消失了。当你开放*,相当于把防御门主动拆了。攻击者在他们自己的页面里做如下结构:

<!-- 恶意页面 --> <div style="opacity: 0; position: absolute; z-index: 999;"> <iframe src="https://your-site.example.com/confirm-payment" width="500" height="300"></iframe> </div> <button style="position: relative; z-index: 1; width: 500px; height: 300px;">点我领取免费皮肤</button>

访客看到的是一个诱人的按钮,实际点击的位置其实是透明 iframe 里的"确认支付"。如果被嵌入页面里有转账、授权、修改资料这类高危操作,后果就很严重了。

所以我的建议是:"允许任何网站嵌入"应该是默认关闭、按需打开的开关,而不是全局默认状态。你可以用页面级 CSP 做更细的隔离,比如只有/embed/路径下的页面开放给所有站点,其他路径保持'self'。如果业务上必须整个域名开放,至少要在自己的页面里加一层 JS 防御作为补充。

4.2 JS 层防御:frame busting 的实用写法

既然响应头已经控制不住"谁能嵌入",那就用 JS 做最后一层防线。最常见的是禁止页面被嵌在非预期环境里:

// 如果不是同源窗口加载,跳回自身 if (window.top !== window.self) { window.top.location = window.self.location; }

但这段代码有 bug:如果被嵌在sandboxiframe 里,window.top.location的赋值会被浏览器拦截,而且如果嵌套层级中有一个沙箱 iframe,你的 JS 都可能无法执行。所以更稳妥的写法是组合判断:

window.addEventListener('DOMContentLoaded', () => { // 检测是否是顶层窗口 const isTop = window.top === window.self; // 检测是否有 sandbox 属性限制 const isSandboxed = !window.top || window.top === window.self; if (!isTop) { // 让嵌入方隐藏这个页面,同时把地址栏带到正常站 document.body.innerHTML = ''; window.location.replace('https://your-site.example.com/'); } });

不过说句大实话,JS 阻断在浏览器安全模型里属于"尽力而为",真正的控制还是应该交给 HTTP 响应头。JS 只能作为响应头失效后的一道额外兜底,尤其是当你对 Safari 老版本无能为力时,JS 能帮你补救一下。

4.3 Cookie 的 SameSite 属性:开放嵌入后最容易忽略的连环坑

页面能嵌入了,随之而来的还有一个特别容易被忽略的问题:cookie。浏览器同源策略里 cookie 的发送规则和 iframe 嵌入决策是两回事。现在主流浏览器默认把 cookie 的 SameSite 设为 Lax,在第三方 iframe 场景下,跨站请求不会自动携带 cookie,也就是说嵌入方网站里嵌入的目标页面,很可能是一个"未登录"状态。

具体表现就是:你在 A.com 嵌 B.com 的后台页面,响应头全放开了、iframe 也显示了,但页面提示登录过期、接口全是 401。这不是响应头的问题,是 B.com 的登录 cookie 没被发过去。

如果业务上确实允许跨站嵌入并且需要维持登录态,目标站得对 cookie 做显式处理:

Set-Cookie: sessionid=xxx; SameSite=None; Secure

SameSite=None必须搭配Secure一起用,也就是要求 HTTPS 环境。这个改动影响面很大,等于把登录 cookie 放开给所有第三方上下文携带,意味着任何站点在用户浏览器里都可能带着这份 cookie 发起请求。安全上建议限定__Host-前缀、缩短有效期、并配合 CSRF Token 做双重校验。做之前一定要和负责安全的人对一下,别自己默默改了。

4.4 更安全的妥协方案:白名单优先于通配符

实际业务里,真正需要"任何网站都能嵌"的场景少之又少。大多数情况下你其实是希望某几个合作方、某几个子域能嵌。用 CSP 白名单就能满足,完全不用开*:

Content-Security-Policy: frame-ancestors 'self' https://partner-a.example.com https://partner-b.example.com;

万一某个合作方用了类似https://sub.partner-a.com的域名,你要注意 CSP 值里https://partner-a.com并不会匹配https://sub.partner-a.com,两者是完全不同的源,得显式写全,或者用通配https://*.partner-a.com。这类"我以为写了白名单结果还是白屏"的情况,我调试时遇到过好几回。

如果业务方死活不肯给域名列表、就要全开放,那至少可以做一个降级方案:默认'self',仅在特定路径、特定参数下返回*。比如/public/下的展示型页面全开放,/account/下的操作型页面一律收紧:

if (req.path.startsWith('/public/')) { res.setHeader('Content-Security-Policy', "frame-ancestors *"); } else { res.setHeader('Content-Security-Policy', "frame-ancestors 'self'"); }

这样既满足了"允许某个网站被任何网站的 iframe 嵌入"的一部分需求,又把高危操作页面的风险控制在可接受范围内。

5. 反查与排错:遇到"还是不能嵌入"怎么办

配置全部到位,但目标页面依然白屏,这种时候最怕瞎猜。我给你一套排查顺序,按这个走,基本能定位九成以上的问题。

5.1 从现象倒推问题

先看控制台报错长什么样,不同的报错指向不同的原因:

报错关键词指向的原因
Refused to display ... because it set 'X-Frame-Options'目标站 XFO 限制
Refused to frame ... because it violates the following Content Security Policy directive: "frame-ancestors ..."目标站 CSP frame-ancestors 限制
Blocked a frame with origin ... from accessing a cross-origin frame嵌入方脚本跨域访问被拦,页面本身可能正常
net::ERR_BLOCKED_BY_RESPONSE响应头被拦截,通常就是 XFO 或 CSP
页面显示但接口全部 401 / 登录态丢失cookie SameSite 问题

5.2 逐步排查的具体动作

第一步:直接访问目标 URL。浏览器单独打开被嵌入的页面,确认页面本身能正常显示、没有跳出 403 或者需要登录跳转。

第二步:curl 看响应头。用前面给的 curl 命令,重点看有没有content-security-policy: frame-ancestors和x-frame-options。如果两个都没有,理论上该页面应该允许任意嵌入(除非有其他反爬机制、UA 校验之类的东西在起作用)。

第三步:确认响应头在重定向链路上是否一致。很多页面访问/embed会 302 到/embed/或者带 token 的地址,重定向的中间响应的响应头里如果也带了 XFO DENY,最终生效的还是会被拦。用输出某个带-L的请求看最终响应:

curl -sL -I https://example.com/embed/page

第四步:检查框架层默认安全头。Spring Security、Helmet、Rack::Protection 这类组件都会悄悄给你加安全响应头,你在服务器层面设的 CSP 可能被它们覆盖或者合并,先确认应用框架层有没有加默认值。

第五步:确认 COOP / CORP 这些新东西有没有掺和。某些情况下,目标站如果设置了Cross-Origin-Opener-Policy: same-origin或Cross-Origin-Resource-Policy: same-origin,也可能影响嵌入行为,尤其是隔离环境下。这个不常见,但排查到最后可以看一眼响应头里有没有这两个字段。

5.3 用本地代理快速验证假设

调这种问题,总在真实环境里来回改配置效率太低。我一般先在本地起个 Nginx 反代,把目标站某个页面转发到本地,然后在响应头上做实验:

location /embed-test/ { proxy_pass https://target-site.example.com/; # 临时覆盖响应头,验证 CSP 是否真的能解决 add_header Content-Security-Policy "frame-ancestors *" always; proxy_hide_header Content-Security-Policy; proxy_hide_header X-Frame-Options; }

这样改完,如果能嵌入了,说明问题就是目标站的响应头;如果还不能嵌入,问题大概率不在响应头,而是别的机制(登录态、路径、反爬)在捣乱。这个"本地改响应头"的验证方式比直接线上调要快很多,也能避免你在生产环境里来回折腾出一堆问题。

实际做这个方案时要注意,很多站点页面里有 CSP 的script-src等指令,你在添加响应头时不要覆盖原有的其他 CSP 指令,最好在已有策略后面追加frame-ancestors *。比如原有策略是script-src 'self'; frame-ancestors 'self',追加后应该是script-src 'self'; frame-ancestors *,如果整条覆盖掉了script-src,页面脚本会被自己站的策略阻断,又是一波新的白屏。

6. 实操记录:一个"全开放嵌入"需求的完整处理过程

我把一个真实的调整过程完整走一遍,方便你照着理解整个链路。

需求方某公司提了个要求:他们内部的看板页面要能被合作伙伴的系统用 iframe 嵌进去,而且合作伙伴特别多、域名不确定,说"只要嵌进去能看就行"。

我当时的处理流程是:

第一步,确认哪些页面需要开放。看板页集中在/board/路径下,一共 6 个路由。其他页面比如用户中心、设置页、导出页都不需要开放。

第二步,页面分级配置。在应用入口处写了一个中间件(这里是 Node.js 的为例,其他语言同理):

app.use((req, res, next) => { if (req.path.startsWith('/board/')) { res.setHeader('Content-Security-Policy', "frame-ancestors *"); // XFO 不设置,防止旧版浏览器的兜底策略冲突 } else { res.setHeader('Content-Security-Policy', "frame-ancestors 'self'"); } next(); });

第三步,处理登录态。看板页要实时数据,要求请求带上用户凭据。本来有个统一的 cookie,SameSite 默认 Lax,嵌入后必然失效。我和后端同事确认后,把看板域名的 cookie 专门设置为SameSite=None; Secure,并且要求所有接口都校验 CSRF Token,防止跨站请求伪造。这里补一点,并不是所有浏览器都执行同一套规则,iOS 的 Safari 在某些版本对SameSite=None处理得不太一样,测试时要在真机上过一遍。

第四步,验证。我写了两个测试页面,分别模拟第三方嵌入和同源嵌入。第三方嵌入页面放在一个完全不同的域名上,iframe 里加载/board/overview。实测 Chrome 和 Firefox 都能显示,Safari 新版也正常。另外用 curl 确认响应头:

content-security-policy: frame-ancestors *

第五步,加兜底。由于某些看板页面允许对外分享,但我不想让这些页面在非预期环境里随意被操作,所以在看板页的 JS 入口做了个轻量检测,不是顶层窗口且document.referrer的来源域名不在公司列表里就提示"如需分享请联系管理员",但不强制跳转——强制跳转会导致合作伙伴的嵌入体验从按钮就断层了。

整个过程下来,最深的一个感受是:全开放嵌入不只是改一行响应头的事,它牵扯到安全策略、cookie、跨域通信、浏览器兼容,是一条链路的改造。文档上写得清清楚楚的是语法,但真正决定能不能落地的是这些边界条件和连环坑。

最后再分享一个个人经验:日常开发时你在本地改完配置,最好把"目标页面的响应头截图"和"嵌入后的页面截图"一起贴到需求沟通里,这样业务方、后端、测试都能一眼看到状态,比写一百字说明都有效。我后来再做类似嵌入需求,都会先问清楚三个问题:嵌入方的域名列表能不能提前给?被嵌入页面里有没有敏感操作?登录态跨站能不能接受?这三个问题定了,方案基本也就定了。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询