Ionic本地开发遇CORS错误,已配置请求头仍报错
我正在本地开发一款使用XHR请求的Ionic应用,但出现了CORS错误。
错误信息
从源'http://localhost:8100'访问'http://id:pwd@mydomain.com/app/proDB.jsonp'的XMLHttpRequest被CORS策略阻止:请求的资源上不存在'Access-Control-Allow-Origin'头。
服务器.htaccess配置(路径:/home/gwwdpcf/www/app/.htaccess)
AuthType Basic AuthName "L pit blod" AuthUserFile /home/gwwdpcf/www/app/.htpasswd require valid-user # Header add Access-Control-Allow-Methods: "GET,POST,OPTIONS,DELETE,PUT" # Header add Access-Control-Allow-Origin "*" # Enable cross domain access control Header add Access-Control-Allow-Origin "*" Header always set Access-Control-Allow-Methods "GET, POST, PUT, DELETE" Header always set Access-Control-Allow-Headers: Authorization Header set Access-Control-Allow-Credentials true # Force to request 200 for options RewriteEngine On RewriteCond %{REQUEST_METHOD} OPTIONS RewriteRule .* / [R=200,L]
客户端代码片段
const url = dbUrl() { return decodeURIComponent(decodeURIComponent("http://example.org/app/proDB.jsonp")) } const username = 'id'; const password = 'pwd'; const credentials = username + ':' + password; const base64Credentials = btoa(credentials); var request = new XMLHttpRequest(); request.open('GET', url, true); request.setRequestHeader('Authorization', 'Basic ' + base64Credentials); request.setRequestHeader('Content-Type', 'application/xml'); // Assuming you're expecting XML data if (url === "proDB.jsonp") { console.log("--Asking local proDB.json..."); } else { console.log("--Sending XMLHttpRequest..."); } request.timeout = XHRtimeout; request.ontimeout = function () { reject({ status: this.status, statusText: request.statusText, }); }; request.onload = async function () { if ( request.readyState === 4 && ((request.status >= 200 && request.status <= 299) || request.status === 304 || request.status === 0) ) { ...
补充截图

问题原因与修复方案
核心问题分析
Basic Auth拦截预检请求
服务器启用了Basic Auth,浏览器发送的OPTIONS预检请求不会携带Authorization头,直接被服务器拦截,导致CORS头无法返回给浏览器,这就是报错提示头不存在的根本原因。CORS配置互斥
Access-Control-Allow-Credentials: true和Access-Control-Allow-Origin: "*"不能同时使用——当允许携带凭证(如Authorization头)时,Origin必须指定具体域名,不能用通配符。OPTIONS请求重定向错误
现有Rewrite规则把OPTIONS请求重定向到根路径/,但根路径的配置和/app/不一致,导致预检请求响应依然缺少CORS头,重定向本身也会触发浏览器的CORS校验失败。
修复步骤
1. 让OPTIONS请求跳过Basic Auth
在Basic Auth配置前添加规则,允许OPTIONS请求无需认证:
RewriteEngine On RewriteCond %{REQUEST_METHOD} OPTIONS RewriteRule ^(.*)$ $1 [R=200,L,E=HTTP_ORIGIN:%{HTTP:ORIGIN}] AuthType Basic AuthName "L pit blod" AuthUserFile /home/gwwdpcf/www/app/.htpasswd require valid-user
2. 修正CORS头配置
替换原CORS配置,指定具体Origin并兼容凭证携带:
# Enable cross domain access control Header always set Access-Control-Allow-Origin "http://localhost:8100" Header always set Access-Control-Allow-Methods "GET, POST, PUT, DELETE, OPTIONS" Header always set Access-Control-Allow-Headers "Authorization, Content-Type" Header always set Access-Control-Allow-Credentials true
3. 移除错误的OPTIONS重定向规则
删掉RewriteRule .* / [R=200,L],改用上面的Rewrite规则处理OPTIONS请求。
4. 客户端验证
保持当前用Authorization头传递凭证的逻辑,避免在URL中直接携带账号密码;确保Content-Type已包含在服务器允许的Headers列表中(已在步骤2配置)。
内容的提问来源于stack exchange,提问作者Louis

