为何XMLHttpRequest在iPhone返回状态码0,浏览器返回200?
状态码0在XMLHttpRequest中通常表示请求被浏览器中止,结合你描述的场景(服务器已执行PHP、直接访问PHP正常),大概率是iPhone默认的Safari浏览器的安全策略或响应配置问题,以下是几个常见原因及解决办法:
跨域资源共享(CORS)配置缺失
直接访问PHP不受同源策略限制,但XHR请求会严格遵循该规则。如果你的HTML页面和PHP接口的域名、端口或协议不完全一致(比如HTML是www.mywebsite.com,PHP是mywebsite.com,或是一个用HTTP一个用HTTPS),Safari会拦截响应——哪怕服务器已经执行了PHP,浏览器也会因为没有正确的CORS头而丢弃结果,返回状态码0。
解决:在PHP脚本开头添加CORS响应头:// 生产环境建议指定具体域名,比如替换*为https://www.mywebsite.com header("Access-Control-Allow-Origin: *"); header("Access-Control-Allow-Methods: GET, POST, OPTIONS"); header("Access-Control-Allow-Headers: Content-Type");HTTPS证书兼容性问题
iPhone Safari对HTTPS证书的要求比桌面浏览器更严格,比如证书过期、域名不匹配、使用了不受信任机构颁发的证书时,直接访问PHP会弹出信任提示,用户确认后就能正常访问,但XHR请求不会弹出提示,会直接中止返回状态码0。
解决:检查SSL证书的有效性,确保证书在iPhone系统中被信任。Safari隐私设置拦截请求
iPhone Safari的「阻止跨站跟踪」功能可能会拦截非同源的XHR请求,尤其是请求带有第三方Cookie时。这种情况下服务器会执行PHP,但浏览器会直接中止响应。
解决:可以先让用户暂时关闭「设置->Safari浏览器->隐私与安全性」里的「阻止跨站跟踪」测试,如果问题解决,建议将接口调整为同源,或是在响应头中给Cookie添加SameSite=None; Secure属性(如果用到Cookie的话)。响应内容格式/编码不兼容
如果PHP输出的编码和HTML页面不一致(比如HTML是UTF-8,PHP输出是GBK),或是PHP文件开头/结尾有多余空白字符,Safari可能会解析失败并中止请求,而桌面浏览器兼容性更强不会出现问题。
解决:统一页面和接口的编码,比如在PHP中添加header("Content-Type: text/html; charset=utf-8");,同时检查PHP文件是否有多余的空白字符。请求超时设置缺失
Safari的XHR默认超时时间可能比桌面浏览器短,如果PHP脚本执行稍久,浏览器会提前判定超时并中止请求,返回状态码0——哪怕服务器后续执行完了PHP。
解决:在XHR代码中添加超时设置:httpr.timeout = 10000; // 设置10秒超时 httpr.ontimeout = function() { alert("请求超时"); };
内容的提问来源于stack exchange,提问作者Jim Wartnick

