jQuery AJAX在iPhone Safari中无法正常工作,求解决方案
我来帮你梳理下这段代码在iOS Safari里跑不通的常见原因,以及对应的解决办法:
1. JSON解析的兼容性坑
你现在是把dataType设为text,然后手动用JSON.parse(data)解析返回结果。但iOS Safari的JSON.parse对格式的严苛程度远超其他浏览器——哪怕返回的JSON里多了个逗号、引号不匹配,甚至服务器返回内容里混了点HTML注释,都会直接解析失败跳去error回调。
解决办法:
直接把dataType改成json,jQuery会自动帮你完成JSON解析,兼容性拉满:
$.ajax({ url: 'http://URLHERE/getHash/' + urlFinal, dataType: 'json', // 替换成json type: 'get', contentType: 'application/x-www-form-urlencoded', success: function( data, textStatus, jQxhr ){ // 这里直接用data,不用再JSON.parse了 console.log("WORKS! " + data.streamFileUrl); $('.overlay').show(); playVideo(data); }, // 其他配置不变 });
2. iOS Safari的GET请求缓存问题
iOS Safari默认会缓存GET请求,哪怕URL参数没变化,也可能直接返回旧的缓存结果,导致你的AJAX根本没发到服务器。而Chrome这类浏览器默认不会缓存这类请求,所以你在其他环境里能正常跑。
解决办法:
在AJAX配置里加cache: false,让jQuery自动给URL加时间戳破缓存:
$.ajax({ url: 'http://URLHERE/getHash/' + urlFinal, dataType: 'json', type: 'get', cache: false, // 禁用缓存 contentType: 'application/x-www-form-urlencoded', // 其他配置不变 });
或者手动给URL拼时间戳:
var urlFinal = callid+'/'+pin + '?t=' + new Date().getTime();
3. 跨域/混合内容限制
如果你的页面是HTTPS协议,AJAX请求却用了HTTP(http://URLHERE/...),iOS Safari会直接阻止这种混合内容请求,而部分桌面浏览器会宽松处理。另外如果请求的域名和当前页面域名不同,服务器没配置正确的CORS响应头,iOS Safari也会拒绝请求。
解决办法:
- 确保页面和AJAX请求用相同的协议(要么全HTTPS,要么全HTTP);
- 检查服务器是否返回了正确的CORS头,比如
Access-Control-Allow-Origin: *(或者指定你的页面域名),如果是带凭证的请求,还要加Access-Control-Allow-Credentials: true。
4. 事件绑定的兼容性问题
虽然你用了$(document).ready绑定submit事件,但如果表单是动态生成的(比如通过其他AJAX加载),或者iOS Safari的事件触发机制有差异,可能导致事件没绑定上。
解决办法:
改用事件委托的方式绑定submit事件,不管表单什么时候生成都能触发:
// 替换原来的$('#form').submit( processForm ); $(document).on('submit', '#form', processForm);
另外把e.preventDefault()移到函数最开头,确保在AJAX发起前就阻止表单默认提交:
function processForm( e ){ e.preventDefault(); // 移到最前面 var callid = $('.callid').val(); var pin = $('.pin').val(); var urlFinal = callid+'/'+pin; // 后面的AJAX代码不变 }
5. 表单元素取值异常
iOS Safari在获取输入框值的时候可能有特殊情况——比如输入框被隐藏、或者页面里有多个相同类名的元素,导致$('.callid').val()或$('.pin').val()取不到正确值,生成错误的URL导致请求失败。
解决办法:
- 尽量用ID选择器代替类选择器(比如
$('#callid').val()),确保选择器唯一; - 在AJAX请求前先打印取值结果到控制台,确认没问题:
console.log('callid:', callid, 'pin:', pin);
内容的提问来源于stack exchange,提问作者Lukas Taylor

