踩坑vue项目中使用 iframe 嵌套子系统无法登录,不报错问题!

前言

最近项目中使用了 iframe 标签进行嵌套子系统时,遇到了无法登录、而且不报错的问题。本文记录自己的踩坑过程,也希望帮助到其他同学。

需求

有两个项目,a项目 和 b项目。 当前开发的 a 项目中需要嵌套展示已上线的 b 项目内容; 且要求 b 项目的功能可以正常使用。

遇到问题

在 a 项目中直接使用 iframe 标签进行嵌套 b 项目来展示。且两个项目部署在不同的服务器下。

  • a 项目:88 服务器
  • b 项目:89 服务器

调试中a 项目可以正常跳转到 b 项目,也能在 iframe 中展示出来, 直接跳转到b 项目的 login 页面后正常调用了登录接口, 且登录接口 200 通了, 返回了用户信息。

但是到这里就没有任何执行了,不会在登录成功后跳转到 b项目的系统首页。

问题分析

页面也没有任何报错,接口也都是通的。 卧槽? 这什么问题?

经过反复测试确实没有任何报错,接口也通了,token等用户信息也正常拿到了,就是不跳转 b 系统首页。

但是我发现当 ifreame 的 url 加载 b项目地址成功显示出 login 登录页面后,点击登录时,页面还会正常走登录接口,此时页面会进行刷新一下 ,也可以获取到 token 等信息,但还是不跳转对应首页。

此时我第一想法就是可能登录成功后被拦截了,导致无法跳转到 home 页。 难道是服务器给拦截了吗?

于是我上网查资料,得到的结果大部分都说是:这种 iframe 嵌套场景因为浏览器的限制,一些 cookie 信息会被拦截导致重定向到了 login 无法正常登录跳转。

问题原因

  • 第三方 Cookie 限制(主要问题)

    • 现代浏览器(Chrome >=80, Safari, Firefox)默认阻止跨域 iframe 的第三方 Cookie
    • 登录依赖的 Session/Cookie 被浏览器阻止写入
  • 同源策略限制

    • iframe 加载的页面与父页面不同源时,无法共享认证状态
  • X-Frame-Options 响应头

    • 目标页面可能设置了 X-Frame-Options: SAMEORIGIN 阻止嵌入
  • 登录逻辑差异

    • iframe 环境可能导致 JS 执行上下文差异(如 window.top 获取失败等问题)

关键代码

先开始我想到这个项目没用到 cookie 相关内容啊。 为了确定,于是尝试在项目里全局查找一下 cookie看看,果然发现了一个文件中包含如下代码:

js 复制代码
import Cookies from 'js-cookie'
const TokenKey = 'saber-access-token'
const RefreshTokenKey = 'saber-refresh-token'
export function getToken() {
    return Cookies.get(TokenKey)
}

export function setToken(token) {
    return Cookies.set(TokenKey, token)
}

export function getRefreshToken() {
  return Cookies.get(RefreshTokenKey)
}

export function setRefreshToken(token) {
  return Cookies.set(RefreshTokenKey, token)
}

export function removeToken() {
    return Cookies.remove(TokenKey)
}

export function removeRefreshToken() {
  return Cookies.remove(RefreshTokenKey)
}

发现该项目使用了 js-cookie 来进行存储 token 等用户信息。

问题解决

经过踩坑,查资料总结一下几种解决方案:

方案1: 确保同源或同站

如果条件允许的话,让 iframe 子内容 和 父页面系统 使用相同的域名(或者至少是相同的顶级域名+相同的协议):

  • 父页面系统: https://app.example.com
  • iframe 子系统: https://service.example.com

方案2: 服务器设置 SameSite

主动设置 SameSite 为 Set-Cookie:Key=Value; SameSite=None; Secure,确保协议为安全协议https

  • Java (Servlet) 配置示例
java 复制代码
Cookie cookie = new Cookie("sessionid", "12345");
cookie.setSecure(true);
cookie.setHttpOnly(true);
cookie.setAttribute("SameSite", "None");
response.addCookie(cookie);
  • Nginx 配置示例
arduino 复制代码
location / {
    proxy_pass http://backend;
    proxy_cookie_path / "/; SameSite=None; Secure";
}

方案3: 禁用浏览器 SameSite 默认限制 (仅测试用)

这只适用于开发和测试环境,不要在生产环境中使用。

  • Chrome 启动参数
ini 复制代码
chrome --disable-features=SameSiteByDefaultCookies
  • 注意事项
  1. 必须使用 HTTPS :SameSite=None 必须与 Secure 属性一起使用,网站必须使用 HTTPS
  2. 浏览器兼容性:检查需要支持的浏览器版本是否支持 SameSite 属性
  3. 测试验证:在 Chrome 开发者工具的 Application > Cookies 部分检查 Cookie 是否正确设置了 SameSite 属性

修改原项目中使用的 cookie 相关代码。直接弃用 js-cookie,使用 localStorage 来存储用户信息。

js 复制代码
// import Cookies from 'js-cookie'
const TokenKey = 'saber-access-token'
const RefreshTokenKey = 'saber-refresh-token'
export function getToken() {
  // return Cookies.get(TokenKey)
  return localStorage.getItem(TokenKey)
}

export function setToken(token) {
  // return Cookies.set(TokenKey, token)
  return localStorage.setItem(TokenKey,token)
}

export function getRefreshToken() {
  // return Cookies.get(RefreshTokenKey)
  return localStorage.getItem(RefreshTokenKey)

}

export function setRefreshToken(token) {
  // return Cookies.set(RefreshTokenKey, token)
  return localStorage.setItem(RefreshTokenKey,token)

}

export function removeToken() {
    // return Cookies.remove(TokenKey)
    return localStorage.remove(TokenKey)
}

export function removeRefreshToken() {
  // return Cookies.remove(RefreshTokenKey)
  return localStorage.remove(RefreshTokenKey)
}

总结

我使用了方案4最简单的方式,直接弃用 js-cookie,改用 localStorage。重新将 b 项目打包部署后,在 a 项目的 iframe 标签内进行嵌套展示,发现登录成功后正常跳转到了 b 项目的首页,且功能正常。

相关推荐
程序员大阳26 分钟前
副队长CSS教程(37)–transition 过渡
前端·css·transition·过渡
ZoeLandia29 分钟前
TypeScript 01:类型注解与类型推断
前端·javascript·typescript
踩蚂蚁34 分钟前
从“打开灯光”看 KWS 多关键词语音控制是怎么工作的
前端
ppiero1 小时前
AI 助手聊着聊着就失忆?先分清"上下文"和"记忆"(五步装长期记忆)
前端
打呵欠的猫1 小时前
用 AI 做性能分析:一行命令找出拖慢页面的 5 个组件,优化后首屏快了 40%
前端·性能优化·ai编程
用户5080070546281 小时前
芯飞云用了两个月,说说我的真实感受
前端
Amos_Web1 小时前
Rspack 源码解析(二十一):Cacheable 与 Storage 如何持久化编译结果
前端·rust·前端框架
青烟小生1 小时前
前端性能优化实战:从指标监控到极致体验
前端
deli0071 小时前
0.1 加 0.2 为什么不等于 0.3?IEEE 754 双精度逐位实测
前端
Momo__1 小时前
前端 Code Review 实战:识别 AI 写代码的 15 个常见坑
前端·vibecoding