如何在Ionic Capacitor应用的每个API请求中添加Access-Control-Allow-Origin头
我把旧的Ionic Angular Cordova应用迁移到Ionic Angular Capacitor后,遇到了CORS相关问题。之前在Cordova里可以通过config.xml做相关配置,现在想知道怎么在Capacitor里设置类似的规则。
原 Cordova config.xml 配置
<access origin="*" /> <allow-intent href="http://*/*" /> <allow-intent href="https://*/*" /> <allow-intent href="tel:*" /> <allow-intent href="sms:*" /> <allow-intent href="mailto:*" /> <allow-intent href="geo:*" />
错误信息
Access to XMLHttpRequest at 'http://service-internal.company.com/service.svc/Authenticate' from origin 'http://127.0.0.1:8100' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource.
新应用环境详情
Ionic: Ionic CLI : 6.20.8 (/opt/homebrew/lib/node_modules/@ionic/cli) Ionic Framework : @ionic/angular 6.6.1 @angular-devkit/build-angular : 15.2.2 @angular-devkit/schematics : 15.2.2 @angular/cli : 15.2.2 @ionic/angular-toolkit : 8.0.0 Capacitor: Capacitor CLI : 4.7.0 @capacitor/android : 4.7.0 @capacitor/core : 4.7.0 @capacitor/ios : not installed Utility: cordova-res : not installed globally native-run : 1.7.2 System: NodeJS : v16.15.0 (/usr/local/bin/node) npm : 8.19.2 OS : macOS Unknown
开发环境(ionic serve 调试)
开发时用ionic serve跑在本地127.0.0.1:8100,浏览器的同源策略会触发CORS限制,Capacitor不支持Cordova那种config.xml配置,改用Angular代理解决:
- 项目根目录新建
proxy.conf.json,内容如下:
{ "/api": { "target": "http://service-internal.company.com", "secure": false, "changeOrigin": true, "pathRewrite": { "^/api": "" } } }
- 修改
angular.json,找到projects -> 你的项目名 -> architect -> serve -> options,添加一行:
"proxyConfig": "proxy.conf.json"
- 之后发起请求时用相对路径,比如把原来的
http://service-internal.company.com/service.svc/Authenticate改成/api/service.svc/Authenticate,代理会自动转发到目标服务器。
生产环境(原生APP)
Capacitor原生APP的HTTP请求不受浏览器同源策略约束,不需要配置类似<access origin="*">的规则,但要注意两个平台的特殊设置:
- Android:如果请求的是HTTP(非HTTPS)地址,需要允许明文流量。要么修改
android/app/src/main/AndroidManifest.xml的<application>标签,添加android:usesCleartextTraffic="true";要么在capacitor.config.ts里配置:
import { CapacitorConfig } from '@capacitor/cli'; const config: CapacitorConfig = { appId: '你的APP ID', appName: '你的APP名称', webDir: 'www', android: { allowMixedContent: true } }; export default config;
- iOS:iOS默认要求HTTPS请求,如果要访问HTTP地址,需要在
capacitor.config.ts里配置内容安全策略,或者修改ios/App/App/Info.plist添加NSAppTransportSecurity例外。推荐在capacitor.config.ts里设置:
ios: { contentSecurityPolicy: 'default-src *; style-src * \'unsafe-inline\'; script-src * \'unsafe-inline\' \'unsafe-eval\'; media-src *;' }
替代 Cordova allow-intent 功能
Capacitor没有直接对应allow-intent的配置,改用@capacitor/launcher插件处理外部链接、电话、短信等操作:
- 先安装插件:
npm install @capacitor/launcher npx cap sync
- 调用示例:
import { Launcher } from '@capacitor/launcher'; // 打开电话 await Launcher.openUrl({ url: 'tel:13800138000' }); // 发送短信 await Launcher.openUrl({ url: 'sms:13800138000' }); // 发送邮件 await Launcher.openUrl({ url: 'mailto:test@example.com' }); // 打开地图 await Launcher.openUrl({ url: 'geo:39.9042,116.4074' });
内容的提问来源于stack exchange,提问作者Abhishek Tomar

