qiankun微前端跨域问题完美解决方案
你是否在使用qiankun构建微前端应用时,频繁遇到"Access-Control-Allow-Origin"错误?是否为不同技术栈的子应用跨域配置感到困惑?本文将从根本原因到实际解决方案,帮你彻底解决qiankun微前端架构中的跨域难题,让你轻松实现主应用与子应用的无缝通信。
读完本文后,你将掌握:
- 微前端跨域问题的本质原因
- 3种服务端跨域配置方案
- 主应用与子应用的跨域代码配置
- 开发环境与生产环境的不同处理策略
- 常见跨域场景的解决方案
跨域问题的根源解析
在微前端架构中,主应用与子应用通常运行在不同的端口或域名下,当主应用通过qiankun加载子应用资源时,浏览器的同源策略会阻止这种跨域请求。qiankun通过fetch API获取子应用的静态资源,这使得跨域问题成为微前端实施过程中的常见障碍。
微前端跨域的三种常见场景
| 场景 | 描述 | 难度 |
|---|---|---|
| 静态资源跨域 | 主应用加载子应用JS/CSS等资源 | ★★☆☆☆ |
| API请求跨域 | 子应用请求后端接口 | ★★★☆☆ |
| Cookie携带跨域 | 跨域请求中携带认证Cookie | ★★★★☆ |
官方文档中明确指出:"qiankun 将会通过 fetch 去获取微应用的引入的静态资源,所以必须要求这些静态资源支持跨域" docs/faq/README.zh-CN.md
服务端跨域解决方案
Nginx配置方案
最常用且推荐的跨域解决方案是在服务端配置CORS头,以Nginx为例:
location / {
# 允许所有域名跨域访问
add_header Access-Control-Allow-Origin *;
# 允许特定域名跨域访问
# add_header Access-Control-Allow-Origin https://main-app.com;
add_header Access-Control-Allow-Methods GET,POST,OPTIONS;
add_header Access-Control-Allow-Headers Content-Type;
# 对于预检请求直接返回204
if ($request_method = 'OPTIONS') {
return 204;
}
}
特别地,对于子应用的HTML文件,建议配置不缓存,确保每次请求都能获取最新内容:
location = /index.html {
add_header Cache-Control no-cache;
add_header Access-Control-Allow-Origin *;
}
Node.js服务端配置
如果你的后端使用Node.js,可以通过以下方式配置CORS:
const express = require('express');
const cors = require('cors');
const app = express();
// 允许所有域名
app.use(cors());
// 或配置特定域名
app.use(cors({
origin: 'https://main-app.com',
credentials: true // 允许携带Cookie
}));
app.listen(3000);
主应用配置方案
Webpack开发环境配置
在开发环境中,可以通过Webpack的devServer配置跨域代理。主应用的webpack.config.js配置如下:
module.exports = {
devServer: {
port: 7099,
headers: {
'Access-Control-Allow-Origin': '*',
},
proxy: {
// 代理子应用API请求
'/api': {
target: 'http://localhost:7101', // 子应用API地址
changeOrigin: true,
pathRewrite: {'^/api': ''}
}
}
}
};
上述配置来自qiankun官方示例项目 examples/main/webpack.config.js,通过设置Access-Control-Allow-Origin: *允许所有域名访问主应用资源。
自定义fetch方法
qiankun允许通过自定义fetch方法来处理跨域请求,特别是需要携带Cookie的场景:
import { start } from 'qiankun';
start({
async fetch(url, ...args) {
// 对需要携带Cookie的请求特殊处理
if (url.includes('/api/auth')) {
return window.fetch(url, {
...args,
credentials: 'include', // 允许跨域请求携带Cookie
});
}
return window.fetch(url, ...args);
},
});
子应用配置方案
Vue子应用配置
Vue子应用需要在vue.config.js中配置跨域相关设置:
module.exports = {
devServer: {
port: 7101,
headers: {
'Access-Control-Allow-Origin': '*',
}
},
configureWebpack: {
output: {
// 把子应用打包成umd库格式
library: `${name}-[name]`,
libraryTarget: 'umd',
jsonpFunction: `webpackJsonp_${name}`,
},
},
};
以上配置来自 examples/vue/vue.config.js,关键在于设置Access-Control-Allow-Origin: *和正确的打包格式。
React子应用配置
React子应用需要在webpack.config.js中进行类似配置:
module.exports = {
devServer: {
port: 7102,
headers: {
'Access-Control-Allow-Origin': '*',
}
},
output: {
library: name,
libraryTarget: 'umd',
jsonpFunction: `webpackJsonp_${name}`,
},
};
上述配置来自 examples/react15/webpack.config.js,确保子应用资源能被主应用跨域访问。
publicPath配置
子应用的静态资源路径必须使用绝对路径,推荐使用运行时publicPath配置:
// 在子应用入口文件的顶部添加
if (window.__POWERED_BY_QIANKUN__) {
// 动态设置publicPath
__webpack_public_path__ = window.__INJECTED_PUBLIC_PATH_BY_QIANKUN__;
}
这种方式可以确保子应用资源始终从正确的路径加载,避免因路径问题导致的404错误。
常见问题解决方案
图片和字体文件跨域
由于qiankun会将外链样式转换为内联样式,导致图片和字体文件的相对路径失效。解决方案有两种:
- 使用CDN地址引用图片和字体文件
- 使用webpack的url-loader将小文件转为base64
// webpack配置
module.exports = {
module: {
rules: [
{
test: /\.(png|jpe?g|gif|webp|woff2?|eot|ttf|otf)$/i,
use: [
{
loader: 'url-loader',
options: {
limit: 4096, // 小于4kb的文件转为base64
},
},
],
},
],
},
};
多实例应用跨域
当同一子应用需要在页面中多次实例化时,需要清除webpack的chunk缓存:
function removeWebpackChunkCacheWhenAppHaveMultiInstance(appName) {
const mountedSameNameApps = document.querySelectorAll(`[data-name^="${appName}"]`);
if (mountedSameNameApps.length > 1) {
mountedSameNameApps.forEach((appContainerElement) => {
appContainerElement.querySelectorAll('script[src]').forEach((script) => {
script.removeAttribute('data-webpack');
});
});
}
}
这段代码来自qiankun源码 packages/qiankun/src/core/loadApp.ts,通过移除data-webpack属性来强制重新加载资源。
微应用间跳转跨域
微应用之间的页面跳转需要特别处理,推荐使用主应用提供的路由实例或history.pushState:
// 微应用内部跳转
function navigateTo(path) {
if (window.__POWERED_BY_QIANKUN__) {
// 通过主应用提供的路由方法跳转
window.mainAppRouter.push(path);
} else {
// 独立运行时使用自身路由
router.push(path);
}
}
跨域解决方案总结
qiankun微前端跨域问题的解决需要从多个层面入手:
- 服务端层面:配置CORS头,允许跨域请求
- 主应用层面:设置正确的响应头,配置代理,自定义fetch
- 子应用层面:配置webpack输出格式,设置publicPath
- 资源层面:使用CDN或base64处理静态资源
通过上述方案的组合应用,可以解决qiankun微前端架构中的几乎所有跨域场景。在实际项目中,建议根据具体情况选择最合适的方案,优先考虑服务端配置和开发环境代理,复杂场景下再使用自定义fetch方法。
最后,推荐参考qiankun官方文档的常见问题部分,获取更多关于跨域及其他问题的解决方案。
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考



