1. Uni-App跨域问题的本质与表现
跨域问题本质上源于浏览器的同源策略(Same-Origin Policy)安全机制。在Uni-App开发中,这个问题会以多种形式出现:
- 开发阶段:使用HBuilderX内置浏览器调试时,访问不同端口的API接口
- 生产环境:H5版本部署后访问第三方服务接口
- 混合编译:某些原生插件需要跨域访问本地资源
典型报错信息包括:
code复制Access to XMLHttpRequest at 'http://api.example.com' from origin 'http://localhost:8080' has been blocked by CORS policy
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 开发环境下的跨域解决方案
2.1 HBuilderX内置浏览器配置
在manifest.json中添加:
json复制"h5": {
"devServer": {
"proxy": {
"/api": {
"target": "http://your-api-server.com",
"changeOrigin": true,
"pathRewrite": {
"^/api": ""
}
}
}
}
}
2.2 本地反向代理方案
对于复杂场景,可创建vue.config.js:
javascript复制module.exports = {
devServer: {
proxy: {
'/api/v1': {
target: 'http://localhost:3000',
ws: true,
changeOrigin: true,
pathRewrite: {
'^/api/v1': '/api'
}
}
}
}
}
3. 生产环境跨域处理策略
3.1 服务端配置CORS
最规范的解决方案是让后端服务添加CORS头:
code复制Access-Control-Allow-Origin: *
Access-Control-Allow-Methods: GET,POST,PUT,DELETE
Access-Control-Allow-Headers: Content-Type
3.2 Nginx反向代理配置
对于无法修改后端的情况,可通过Nginx转发:
nginx复制location /api/ {
proxy_pass http://backend-server/;
add_header 'Access-Control-Allow-Origin' '*';
add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
}
4. 多端环境适配方案
4.1 动态环境变量管理
创建config.js:
javascript复制const env = process.env.NODE_ENV
const configMap = {
development: {
baseUrl: 'http://localhost:3000/api'
},
production: {
baseUrl: 'https://api.yourdomain.com'
}
}
export default configMap[env]
4.2 条件编译处理差异
在请求封装层处理平台差异:
javascript复制// #ifdef H5
const baseURL = '/api'
// #endif
// #ifdef MP-WEIXIN
const baseURL = 'https://api.weixin.com'
// #endif
5. 图片资源的跨域处理
5.1 图片mode属性配置
html复制<image
src="https://cross-domain.com/image.jpg"
mode="aspectFit"
@error="handleImageError"
></image>
5.2 代理中转方案
对于严格限制跨域的图片资源:
javascript复制function getProxyImage(url) {
return `https://your-proxy-server.com/fetch?url=${encodeURIComponent(url)}`
}
6. 常见问题排查指南
6.1 预检请求(OPTIONS)失败
确保服务端正确处理OPTIONS方法:
javascript复制// Express示例
app.options('*', (req, res) => {
res.header('Access-Control-Allow-Methods', 'GET,PUT,POST,DELETE')
res.status(204).send()
})
6.2 带凭证的请求问题
当需要发送cookie时:
javascript复制// 前端设置
uni.request({
url: 'https://api.example.com',
withCredentials: true
})
// 服务端必须配置
Access-Control-Allow-Credentials: true
Access-Control-Allow-Origin: 'https://yourdomain.com' // 不能是*
7. 高级配置技巧
7.1 Webpack自定义配置
在vue.config.js中扩展:
javascript复制configureWebpack: {
devServer: {
headers: {
'Access-Control-Allow-Origin': '*',
}
}
}
7.2 原生平台特殊处理
对于Android平台,可能需要修改原生配置:
xml复制<!-- AndroidManifest.xml -->
<application
android:usesCleartextTraffic="true">
8. 安全最佳实践
- 生产环境避免使用通配符(*)
- 严格限制允许的HTTP方法
- 对敏感接口实施CSRF防护
- 定期审计CORS配置
javascript复制// 安全配置示例
app.use((req, res, next) => {
const allowedOrigins = ['https://yourdomain.com', 'https://app.yourdomain.com']
const origin = req.headers.origin
if (allowedOrigins.includes(origin)) {
res.header('Access-Control-Allow-Origin', origin)
}
next()
})
9. 性能优化建议
- 预检请求缓存:
code复制Access-Control-Max-Age: 86400
- 合并API请求减少预检次数
- 对静态资源使用CDN加速
- 启用HTTP/2减少连接开销
10. 测试验证方案
10.1 自动化测试脚本
javascript复制describe('CORS测试', () => {
it('应允许跨域请求', async () => {
const res = await request(app)
.get('/api/test')
.set('Origin', 'http://test.com')
expect(res.headers['access-control-allow-origin']).toEqual('http://test.com')
})
})
10.2 多端真机测试清单
- iOS Safari浏览器
- Android Chrome浏览器
- 微信小程序WebView
- 支付宝小程序容器
- 各平台原生渲染模式
