Safari(iOS及OS X)最新更新后Ajax文件上传功能失效
解决Safari最新版本中jQuery $.ajax + FormData上传故障的方案
我之前帮开发者排查过好几起类似的问题,最新版Safari(不管是iOS还是macOS)更新后,对jQuery的$.ajax结合FormData的上传请求确实有一些兼容性细节需要调整。下面是几个经过实际验证的解决方案,你可以逐一尝试:
1. 改用原生XMLHttpRequest替代jQuery $.ajax
很多时候,jQuery对AJAX请求的封装会在请求头处理上和Safari的新规则冲突,直接用浏览器原生的XMLHttpRequest API能绕过这些问题。这也是我最推荐的方案,代码示例如下:
const xhr = new XMLHttpRequest(); xhr.open(method, url); // 处理成功响应 xhr.onload = function() { if (xhr.status >= 200 && xhr.status < 300) { const data = xhr.responseText; // 这里处理返回的数据,和你之前success里的逻辑一致 } else { console.error('请求失败:', xhr.status, xhr.statusText); } }; // 处理网络错误 xhr.onerror = function() { console.error('发生网络错误'); }; // 设置超时 xhr.timeout = 30000; xhr.ontimeout = function() { console.error('请求超时'); }; // 发送FormData xhr.send(formData);
原生API不会额外添加不必要的请求头,完全遵循浏览器的默认处理逻辑,适配Safari的概率最高。
2. 调整jQuery $.ajax的配置参数
如果你不想放弃jQuery,可以尝试修改配置,消除可能触发Safari兼容性问题的设置:
$.ajax({ url: url, type: method, data: formData, contentType: false, processData: false, // 阻止jQuery自动添加X-Requested-With请求头,Safari对这个头的处理有变化 headers: { 'X-Requested-With': undefined }, // 强制禁用缓存,避免Safari的缓存机制干扰上传请求 cache: false, success: function(data) { // do some stuff with data }, timeout: 30000, error: function(jqxhr,status,error) { console.log(jqxhr); // 建议在这里打印更详细的错误信息,方便排查 console.log('错误详情:', jqxhr.responseText, error); } });
关键的调整是移除X-Requested-With头,最新Safari对这个AJAX标识头的校验更严格,jQuery默认会添加它,可能导致请求被异常处理。
3. 检查FormData的构建是否规范
有时候问题出在FormData的创建过程中,Safari对FormData的格式要求比其他浏览器更严格:
- 优先直接从表单元素初始化FormData,而不是手动逐个添加字段:
// 推荐的构建方式 const formElement = document.querySelector('your-form-selector'); const formData = new FormData(formElement); // 如果需要额外字段,再用append添加 formData.append('extra_key', 'extra_value'); - 不要手动修改FormData的
Content-Type头,让浏览器自动生成带正确边界的请求头 - 确保添加的文件对象是有效的,避免在文件还未完全选中就构建FormData
4. 排查服务器端的接收逻辑
如果前端调整后还是不行,可能是服务器端对Safari发送的请求处理有问题:
- 确认服务器端能正确解析
multipart/form-data格式的请求,尤其是边界符的处理 - 检查服务器是否有基于User-Agent的拦截或特殊处理,导致Safari的请求被拒绝
- 查看服务器的访问日志,确认请求是否正常到达,以及请求体的格式是否符合预期
内容的提问来源于stack exchange,提问作者acb1980
相关产品推荐
相关产品推荐

