JS请求Roblox接口报读取undefined的name属性错误如何解决
报错根因
触发该TypeError有3个直接原因:
request库默认返回的body是JSON格式的字符串,不是解析完成的JS对象,字符串本身不存在data属性,读取body.data得到的值为undefined,再往下读取name属性就会抛出类型错误- Roblox该游戏查询接口的返回结构中,
data字段是数组类型,不是单个对象,即使完成JSON解析,直接读取data.name也会拿到undefined,你传入的universeId对应的游戏数据实际存放在data[0]中 - 代码没有做任何错误分支处理:请求报错、接口返回非200状态码、返回格式异常时,响应体根本不会存在预期的
data结构,直接读取深层属性必然触发错误
错误信息:
Cannot read properties of undefined (reading 'name')
排查步骤
- 在请求回调第一行打印
typeof body和原始body内容,就能确认默认拿到的是字符串类型返回值,而非可直接读取属性的JS对象 - 将返回内容解析为JSON后打印完整结构,就能看到
data是数组类型,需要按下标取元素才能拿到具体的游戏属性 - 逐段校验属性读取链路:原始响应体 -> 解析后的JS对象 ->
data字段 ->data数组长度 -> 数组元素的name字段,每一步确认值存在后再往下读取
修复后代码
const request = require('request'); function loop(){ request.get({ url: 'https://games.roblox.com/v1/games?universeIds=3652651589', rejectUnauthorized: false, // 加json:true可以让request自动解析响应为JS对象,省掉手动JSON.parse步骤 json: true, headers: { 'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/72.0.3750.0 Iron Safari/537.36' } }, (err, res, body) => { // 先处理请求层错误 if (err) { console.error('请求失败:', err.message); setTimeout(loop, 5000); return; } // 校验接口状态码 if (res.statusCode !== 200) { console.error('接口返回异常状态码:', res.statusCode, body); setTimeout(loop, 5000); return; } // 校验data字段结构 if (!Array.isArray(body.data) || body.data.length === 0) { console.error('接口返回data字段异常:', body); setTimeout(loop, 5000); return; } // 取数组第一个元素读取游戏名称 console.log('游戏名称:', body.data[0].name); // 定时器放在回调内,避免请求耗时长时堆积并发请求 setTimeout(loop, 5000); }); } loop();
优化说明
- 所有外部接口请求都不要假设返回结构永远符合预期,读取深层属性前必须做存在性校验,避免接口限流、返回错误页、服务端异常时直接抛错,导致整个轮询进程中断
- 原代码将
setTimeout(loop, 5000)写在请求发起的同步逻辑中,不管接口响应耗时多久,都会固定每5秒发起一次新请求。如果接口响应时间超过5秒,会同时存在多个未完成的请求,长时间运行会堆积大量请求占用内存。将定时器移到请求回调内,可以保证上一次请求处理完成后,再等待5秒发起下一次请求,运行更稳定 - 如果轮询时频繁触发限流,可以适当拉长轮询间隔,或者增加失败退避逻辑:请求失败时将等待时间加倍,减少被接口拦截的概率
内容的提问来源于stack exchange,提问作者poorguy
相关产品推荐
相关产品推荐

