qiankun微应用加载第三方js跨域报错

文章介绍了在使用qiankun框架时遇到的跨域问题,以及如何通过excludeAssetFilterAPI和动态加载来解决。通过定义白名单和添加特定协议_custom-exclude_=_MAIN到资源链接,可以避免qiankun的静态资源拦截,简化了支持跨域的复杂性。此外,还提供了一种动态加载脚本的方法以适应更多的第三方资源需求。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

当我们在qiankun微应用,引入第三方js脚本时会产生跨域问题并报错,看qiankun的解释:常见问题 - qiankun

qiankun会把静态资源的加载拦截,改用fetch方式获取资源,所以要求这些资源支持跨域。

虽然qiankun也提供了解决方案,但支持跨域的方式也颇为复杂,有没有更简单的方式,纯前端实现?

幸在qiankun提供了excludeAssetFilter API 说明 - qiankun

解决方案:

步骤1 — 将资源写入主应用(基座) excludeAssetFilter 的放行规则里

步骤2 — 将资源加载方式改为动态加载

假如,我们需要加载的第三方脚本链接是 https://xxxx.yyy.com/sdk/xxx-1.0.0.js

可以在如下主应用里通过定义白名单脚本链接 whiteList ,直接放行该脚本。

当我们需要放行的第三方脚本越来越多,需要在 whiteList 里人工添加需要放行的脚本链接,后续维护成本高。

可以通过制定一个协议,如下,协议关键字 _custom-exclude_=MAIN

微应用里需要放行的资源,开发者自行在链接上带上放行协议关键字即可。一劳永逸。

start({
  prefetch: false,
  excludeAssetFilter: assetUrl => { // 指定部分特殊的动态加载的微应用资源(css/js) 不被 qiankun 劫持处理
    // 自定义白名单链接
    const whiteList = ['https://xxxx.yyy.com/sdk/xxx-1.0.0.js', 'https://ccc.ttt.com/js/xxx-1.0.0.min.js']
    /**
     * 白名单协议:子应用下如需要放行动态加载的css/js资源,可以在链接上带上参数 _custom-exclude_=MAIN
     */
    const whiteWords = ['_custom-exclude_=MAIN'] // 白名单关键词:协议制定 _custom-exclude_=MAIN。
    if (whiteList.includes(assetUrl)) {
      return true
    }
    return whiteWords.some(w => {
      return assetUrl.includes(w)
    })
  },
  ......
})

子应用加载该脚本方式改为动态加载方式(可自行实现,或者直接使用示例代码)。

例如,新建如下文件

src/utils/loadScript.js

const loadScript = (url) => {
  let script = document.createElement('script')
  script.setAttribute('type', 'text/javascript')
  script.setAttribute('src', url)
  let head = document.getElementsByTagName('head')
  if (head.length) {
    head[0].appendChild(script)
  } else {
    document.documentElement.appendChild(script)
  }
}
 
loadScript('https://xxxx.yyy.com/sdk/xxx-1.0.0.js?_custom-exclude_=MAIN')  // 需要放行的脚本1
loadScript('https://ccc.ttt.com/js/xxx-1.0.0.min.js?_custom-exclude_=MAIN') // 需要放行的脚本2

在src/main.js文件内引入上面的脚本即可

import '@/utils/loadScript'

### JavaScript 中使用第三方库时出现错误的解决方案 在 Nuxt 或 Next.js 等基于服务端渲染 (SSR) 的框架中,由于 `document` 和 `window` 对象仅存在于浏览器环境中而不在服务器端可用,因此当引入依赖这些对象的第三方库时,通常会遇到诸如 `document is not defined` 或 `window is not defined` 的错误[^1]。 #### 错误原因分析 这类错误的根本原因是某些第三方库试图访问全局变量 `document` 或 `window`,但在 SSR 流程中的服务器阶段,这些变量尚未初始化。这导致运行时抛出异常并中断程序执行。 --- #### 解决方案一:条件加载客户端代码 可以通过检测当前环境来决定是否加载特定代码。例如,在 Nuxt.js 或 Next.js 中可以利用 `process.client` 来区分客户端和服务端: ```javascript if (process.client) { const library = require('third-party-library'); // 使用 third-party-library 提供的功能 } ``` 这种方式确保只有在客户端环境下才会尝试加载和调用涉及 `document` 或 `window` 的代码。 --- #### 解决方案二:动态导入 (`dynamic import`) 对于支持动态导入的框架(如 Next.js),推荐使用动态导入的方式延迟加载可能引发冲突的模块: ```javascript const LibraryComponent = dynamic(() => import('third-party-library'), { ssr: false }); function MyComponent() { return ( <div> {/* 动态加载组件 */} <LibraryComponent /> </div> ); } export default MyComponent; ``` 通过设置 `{ ssr: false }` 参数,可以让该组件跳过服务端渲染过程,从而避免因缺少 `window` 导致的错误[^3]。 --- #### 解决方案三:修改 Webpack 配置 如果上述方法无法解决问题,则可考虑调整构建工具配置文件以忽略相关依赖项。以下是针对 Next.js 的一个例子: 编辑 `next.config.js` 文件,添加以下内容: ```javascript module.exports = { webpack(config, options) { config.externals.push({ 'some-third-party-library': true, }); return config; }, }; ``` 此操作告诉 Webpack 不要打包指定的第三方库到最终产物中,而是让其在运行时由浏览器自行处理[^4]。 --- #### 如果是 iframe 嵌套引起的安全问题 有时报错可能是由于页面被其他站点通过 `<iframe>` 方式嵌入而导致的安全限制触发。此时需确认是否有合适的 CORS 设置以及验证逻辑是否存在漏洞。具体做法包括但不限于检查 HTTP 头部字段 `X-Frame-Options` 是否允许子帧显示目标资源;或者借助 JavaScript 判断当前上下文是否处于顶层窗口之外的位置[^2]: ```javascript if (window.top !== window.self) { console.warn("This page should not be loaded inside an iframe."); // 可选行为:重定向至独立地址或阻止进一步交互 } ``` --- ### 总结 以上介绍了几种常见场景下应对 JavaScript 第三方库集成过程中可能出现的各种兼容性难题的办法。实际应用时应视具体情况灵活选用最适合的技术手段加以克服。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值