静态生成Nuxt应用时Store中Axios数据调用map方法报错解析
Nuxt静态构建后出现
TypeError: h.map is not a function报错解决 报错信息
开发模式运行完全正常,执行nuxt generate生成静态包后,页面运行抛出如下错误:
TypeError: h.map is not a function at 53f3259.js:formatted:3500 at v (c554bee.js:2) at Generator._invoke (c554bee.js:2) at Generator.next (c554bee.js:2) at r (c554bee.js:2) at l (c554bee.js:2)
相关代码
两个触发报错的Vuex Store Action,都包含对axios返回结果执行map遍历的逻辑:
Action 1:嵌套请求列表数据
逻辑为:先获取主列表,再逐个请求每条主数据的关联子数据,全部加载完成后更新状态:
async getParlamenty({ state, commit }) { if (state.parlamenty.length) return; try { let parlamenty = await this.$axios.get('/Api/snemovny/seznam'); parlamenty = parlamenty.data; return Promise.all(parlamenty.map( async (parlament) => { parlament.SnemovniObdobi = await this.$axios.get(`/Api/snemovny/${parlament.Id}`); parlament.SnemovniObdobi = parlament.SnemovniObdobi.data.SnemovniObdobi; return parlament; })).then((res) => { commit("updateParlamenty", parlamenty); }); } catch (err) { console.log(err); } },
Action 2:仅做返回结果格式化
逻辑为:获取列表后直接做字符串格式化,无嵌套请求:
async getPoslanciSeznam({ state, commit, dispatch }, {limit = 20, stranka = 1, filterCallback = null} ) { if (state.poslanci.length) return; try { let poslanci = await this.$axios.get(`/Api/osoby?limit=${limit}&stranka=${stranka}`).then(res => res.data); if (filterCallback !== null) { poslanci = poslanci.filter(filterCallback); } poslanci = poslanci.map((poslanec) => { if (poslanec.DatumNarozeniZobrazene !== null) { poslanec.DatumNarozeniZobrazene = poslanec.DatumNarozeniZobrazene.split('. ')[2]; } if (poslanec.DatumUmrtiZobrazene !== null) { poslanec.DatumUmrtiZobrazene = poslanec.DatumUmrtiZobrazene.split('. ')[2]; } return poslanec; }); commit("updatePoslanci", poslanci); dispatch('countPoslanciStatistiky'); } catch (err) { console.log(err); } }
排查过程
最初的猜测点:
- 对axios返回结果赋值后调用
map是否存在兼容问题? - 循环内嵌套调用axios的写法会不会导致返回数据结构异常?
- 是否需要显式返回
Promise.all才能保证数据加载完成?
但第二个Action无嵌套请求、仅做简单的字符串处理,同样触发报错,直接排除了前两个猜测;同时Promise.all的返回值不影响后续提交的parlamenty数组结构,也不属于报错原因。
问题根源
最终定位到是nuxt.config.js配置导致的:
- 构建静态包时设置了
ssr: false,Nuxt不会在构建阶段预取任何API请求,所有接口请求全部放到客户端运行时执行 - 客户端直接请求API地址时触发CORS跨域限制,接口请求失败后拿到的响应不是预期的数组结构,因此调用
Array.map时抛出类型错误
开发模式下因为Nuxt内置同域运行环境、自动处理接口代理,不会触发CORS问题,所以所有逻辑都能正常运行。
解决方案
根据业务需求选择即可:
- 需要静态构建阶段预取所有接口、生成完全静态页面:将
nuxt.config.js中的ssr配置改为true,重新执行nuxt generate - 坚持关闭SSR、使用纯客户端渲染静态包:需要给API服务配置跨域允许响应头,或配置axios代理规则避免CORS问题
内容的提问来源于stack exchange,提问作者Jakub Albert Ferenc
相关产品推荐
相关产品推荐

