别再为UniApp H5跨域发愁了!manifest.json和vue.config.js两种代理配置,我帮你踩完坑了
UniApp H5跨域实战指南:manifest.json与vue.config.js的深度解析
第一次在UniApp H5开发中遇到跨域问题时,我盯着浏览器控制台里那个鲜红的CORS错误提示发呆了半小时。和大多数新手开发者一样,我按照网上教程配置了manifest.json,却发现项目依然报错。更令人抓狂的是,错误信息竟然变成了"Please enable JavaScript to continue"——这跟跨域有什么关系?经过多次踩坑后,我意识到跨域配置远不止复制粘贴几行代码那么简单。
1. 跨域问题的本质与UniApp的特殊性
跨域问题本质上是浏览器出于安全考虑实施的同源策略限制。当你的前端应用运行在http://localhost:8080,而API服务位于http://api.example.com时,浏览器会阻止这种跨域请求。在传统Vue项目中,我们通常通过vue.config.js配置代理解决这个问题,但UniApp作为多端统一框架,有其独特的处理机制。
UniApp的H5模式实际上是在Vue基础上封装而来,因此它同时支持两种代理配置方式:
- manifest.json配置:UniApp特有的配置文件,优先级更高
- vue.config.js配置:标准Vue项目的配置方式,灵活性更强
有趣的是,很多开发者不知道这两种配置同时存在时会发生什么。我曾在一个项目中同时配置了二者,结果发现请求根本不会发送到预期的目标地址。这就是为什么理解它们的优先级和生效条件如此重要。
2. manifest.json配置详解与避坑指南
2.1 基础配置方法
在UniApp项目的manifest.json文件中进行H5代理配置,需要切换到"源码视图"。以下是完整的配置示例:
"h5": { "devServer": { "disableHostCheck": true, "proxy": { "/api": { "target": "http://your-api-domain.com", "changeOrigin": true, "secure": false, "pathRewrite": { "^/api": "" } } } } }关键参数说明:
disableHostCheck: 禁用主机检查,解决Invalid Host header问题target: 实际API服务器地址changeOrigin: 修改请求头中的Origin为目标地址pathRewrite: 重写请求路径,通常用于移除统一前缀
2.2 常见问题排查
问题1:修改配置后不生效
- 确保保存了文件
- 重新运行项目(
npm run dev:h5) - 在HBuilderX中,有时需要完全重启IDE
问题2:出现"Please enable JavaScript to continue"错误这个看似与跨域无关的错误实际上可能是代理配置不正确的表现。解决方法包括:
- 检查代理目标地址是否正确
- 确认路径重写规则是否匹配实际请求
- 清除浏览器缓存后重试
问题3:热更新后代理失效这是UniApp开发中的一个已知问题。临时解决方案是:
- 停止开发服务器
- 删除
.hbuilderx和unpackage目录 - 重新启动项目
提示:manifest.json的配置修改后,必须重新编译才能生效,简单的热更新不会触发代理配置更新。
3. vue.config.js配置的灵活应用
3.1 标准配置方式
在项目根目录创建vue.config.js文件(注意:必须严格在根目录):
module.exports = { devServer: { disableHostCheck: true, proxy: { '/api': { target: 'http://your-api-domain.com', changeOrigin: true, secure: false, pathRewrite: { '^/api': '' } } } } }虽然看起来与manifest.json配置相似,但vue.config.js提供了更多高级选项:
// 高级配置示例 proxy: { '/api': { target: 'http://your-api-domain.com', bypass: function(req, res, proxyOptions) { // 动态绕过代理的逻辑 if (req.headers.accept.indexOf('html') !== -1) { return '/index.html'; } } } }3.2 多环境配置策略
在实际项目中,我们通常需要区分开发、测试和生产环境。vue.config.js可以方便地实现这一点:
const ENV = process.env.NODE_ENV; const apiMap = { development: 'http://dev-api.example.com', test: 'http://test-api.example.com', production: 'http://api.example.com' }; module.exports = { devServer: { proxy: { '/api': { target: apiMap[ENV], // 其他配置... } } } }配合package.json中的脚本命令:
"scripts": { "dev:h5": "cross-env NODE_ENV=development uni build -p h5", "test:h5": "cross-env NODE_ENV=test uni build -p h5" }4. 两种配置的优先级与选择策略
4.1 优先级实验
通过以下实验可以验证配置的优先级:
- 在manifest.json中配置
target: 'http://source-a.com' - 在vue.config.js中配置
target: 'http://source-b.com' - 观察请求实际发送到哪个地址
结果会发现请求总是发送到manifest.json配置的地址,证明manifest.json的优先级更高。
4.2 配置选择建议
根据项目需求选择合适的配置方式:
| 考虑因素 | manifest.json | vue.config.js |
|---|---|---|
| 配置优先级 | 高 | 低 |
| 多端统一 | 适合(UniApp原生支持) | 仅H5有效 |
| 配置复杂度 | 简单 | 更灵活 |
| 环境区分 | 需要手动处理 | 可通过Node环境变量区分 |
| 热更新支持 | 需要重启 | 部分情况支持热更新 |
推荐场景:
- 简单项目:使用manifest.json即可
- 复杂H5项目:优先使用vue.config.js
- 需要严格多端一致:使用manifest.json
5. 实战中的请求封装技巧
无论采用哪种代理配置,良好的请求封装都能提升开发效率。以下是一个支持自动区分环境的请求封装示例:
// utils/request.js // 环境自动判断 const getBaseHost = () => { // H5环境使用代理前缀 if (process.env.UNI_PLATFORM === 'h5') { return '/api'; } // 其他平台使用完整地址 return { 'mp-weixin': 'https://wx-api.example.com', 'app-plus': 'https://app-api.example.com' }[process.env.UNI_PLATFORM] || 'https://default-api.example.com'; }; const request = (options) => { return new Promise((resolve, reject) => { uni.request({ url: getBaseHost() + options.url, method: options.method || 'GET', data: options.data || {}, header: { 'Content-Type': 'application/json', 'X-Token': uni.getStorageSync('token'), ...options.headers }, success: (res) => { // 统一处理响应 if (res.statusCode === 200) { resolve(res.data); } else { reject(res); } }, fail: (err) => { reject(err); } }); }); }; // 示例用法 export const getUserInfo = () => request({ url: '/user/info' }); export const login = (data) => request({ url: '/auth/login', method: 'POST', data });这种封装方式可以:
- 自动适配不同平台的API地址
- 统一处理授权信息
- 提供Promise风格的API
- 简化业务代码中的请求调用
6. 调试技巧与性能优化
6.1 代理调试技巧
当代理配置不工作时,可以按照以下步骤排查:
- 检查网络请求是否真的经过代理(浏览器开发者工具)
- 确认路径重写规则是否正确
- 查看控制台和终端有无错误输出
- 尝试简单的curl命令测试代理服务器
# 测试代理是否工作 curl -v http://localhost:8080/api/user6.2 性能优化建议
代理配置不当可能导致性能问题:
- 避免过度使用路径重写,增加匹配开销
- 对于大量静态资源请求,考虑直接绕过代理
- 在生产环境禁用开发代理配置
// 生产环境禁用代理 if (process.env.NODE_ENV === 'production') { delete module.exports.devServer.proxy; }在一次性能优化中,我发现某个项目的首屏加载特别慢。经过排查,原来是代理配置错误导致所有静态资源请求都尝试经过代理。修正后,加载时间从4秒降到了1秒以内。
