
`window.screen` 是不可直接序列化的 dom 对象,需手动提取关键属性(如宽高、色彩深度等)再发送,否则 ajax 请求会静默失败。
在 Web 开发中,常需将前端设备屏幕信息(如分辨率、可用区域、方向等)上报至后端用于统计分析、响应式策略或 A/B 测试。但直接赋值 data.w = window.screen 会导致 jQuery 的 $.ajax() 请求完全不发出——这是因为 window.screen 是一个非可枚举、不可序列化的宿主对象,其大部分属性(如 availWidth、height)虽可读取,但默认不被 JSON.stringify() 遍历(JSON.stringify 仅处理对象自身的可枚举自有属性,且要求值为基本类型、数组或可序列化对象)。
当 data 包含 window.screen 时,jQuery 在内部调用 jQuery.param()(非 JSON.stringify)处理 application/x-www-form-urlencoded 数据;而该方法对复杂对象(尤其是 DOM 接口实例)的序列化行为未定义,常导致参数丢失或请求中断,表现为 Network 面板无请求记录。
✅ 正确做法:显式提取所需属性,构建纯 JSON 友好对象:
const screenData = {
availWidth: window.screen.availWidth,
availHeight: window.screen.availHeight,
width: window.screen.width,
height: window.screen.height,
colorDepth: window.screen.colorDepth,
pixelDepth: window.screen.pixelDepth,
orientationType: window.screen.orientation?.type || 'unknown',
orientationAngle: window.screen.orientation?.angle || 0
};
$.ajax({
method: 'POST',
url: '/tested-route',
crossDomain: true,
contentType: 'application/x-www-form-urlencoded', // 注意:此处不应设为 false
headers: {
'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('value'),
'Accept': 'application/json'
},
data: {
screen: JSON.stringify(screenData) // ✅ 序列化为字符串,后端解析
// 或直接展开:...screenData
},
success: function(response) {
console.log('Screen info sent successfully:', response);
},
error: function(jqXHR, textStatus, errorThrown) {
console.error('AJAX failed:', textStatus, errorThrown);
}
});⚠️ 关键注意事项:
- 不要将 contentType: false 与表单数据混用(它适用于 FormData 上传场景),此处应明确指定 'application/x-www-form-urlencoded';
- window.screen.orientation 是实验性 API,需加空值检查(如 ?. 可选链)以避免 Safari 等环境报错;
- 若后端使用 JSON 解析(如 Express 的 body-parser.json()),建议统一 contentType: 'application/json' 并发送 JSON.stringify({screen: screenData});
- 避免传递敏感信息(如精确像素值可能助于指纹识别),生产环境应评估隐私合规性。
总结:永远不要直接传递 DOM 对象(window.screen、document、event 等)给 AJAX 的 data 字段。坚持“按需提取、显式构造、安全序列化”三原则,即可稳定、高效地完成前端设备信息上报。

