在React+TypeScript+Ionic中DOM加载后使用Axios获取XML数据并解决请求中止问题以填充IonSelect组件的方法
修复Axios "Request aborted" 错误并填充IonSelect数据
我来帮你一步步解决这两个问题:先搞定Axios的请求中止错误,再把获取到的XML数据填充到IonSelect组件里。
一、修复"Request aborted"错误
这个错误大多和请求生命周期管理、网络配置有关,我们从几个核心点入手修复:
1. 让请求函数返回Promise并支持取消操作
你的getFornecedores之前没有返回Axios请求的Promise,也没处理请求取消逻辑,当组件卸载或重新渲染时,浏览器会自动中止未完成的请求。我们修改函数,加入AbortSignal支持:
export function getFornecedores(signal?: AbortSignal) { console.log("Dentro do getFornecedores"); // 返回整个Axios请求的Promise,同时传入AbortSignal用于取消请求 return axios.get(config.web_service_url + "/TM_GetEnt?pEntTp=F", { responseType: 'document', timeout: 10000, // 添加超时时间,避免请求无限挂起 signal: signal, }) .then( (response) => { console.log(response); return response; }) .catch((err) => { console.error("Axios falhou:", err); // 抛出错误让调用方处理 throw err; }) }
2. 在组件中管理请求生命周期
在Validacao组件里,用AbortController控制请求的取消,避免组件卸载时请求被意外中止:
// 先添加状态管理选项数据(后面会用到) const [fornecedoresOptions, setFornecedoresOptions] = React.useState<{value: string; text: string}[]>([ { value: "", text: "Escolha uma opção" } ]); useEffect(() => { const abortController = new AbortController(); // 用async/await处理异步请求 const fetchFornecedores = async () => { try { // 传入AbortSignal const response = await getFornecedores(abortController.signal); // 解析XML数据并更新选项 parseXMLAndUpdateSelect(response.data); } catch (err) { // 区分请求取消和其他错误 if (axios.isCancel(err)) { console.log('请求被取消:', err.message); } else { console.error('获取供应商数据失败:', err); } } }; fetchFornecedores(); // 清理函数:组件卸载或依赖变化时取消请求 return () => abortController.abort('组件卸载,取消请求'); }, []); // 用空数组确保只在组件挂载时执行一次请求
3. 排查其他可能的原因
如果修改后仍报错,检查以下几点:
- CORS配置:后端服务器是否允许你的前端域名跨域请求?需要后端添加
Access-Control-Allow-Origin等响应头。 - URL正确性:确认
config.web_service_url拼接后的完整URL能在浏览器直接访问,参数pEntTp=F是否符合后端要求。 - 网络环境:检查是否有代理、防火墙拦截了请求。
二、将XML数据填充到IonSelect组件
因为响应是XML格式,我们需要解析XML并更新组件的选项状态:
1. 编写XML解析函数
根据你的XML响应结构(这里假设XML包含<Fornecedor>节点,每个节点有id属性和名称文本,你需要根据实际结构调整):
const parseXMLAndUpdateSelect = (xmlDoc: Document) => { // 选择所有供应商节点,替换成你实际的XML节点名 const fornecedorNodes = xmlDoc.querySelectorAll('Fornecedor'); // 转换为选项数组 const newOptions = Array.from(fornecedorNodes).map(node => { // 从XML节点中提取值和文本,根据实际结构修改 const fornecedorId = node.getAttribute('id') || ''; const fornecedorNome = node.textContent?.trim() || 'Nome não disponível'; return { value: fornecedorId, text: fornecedorNome }; }); // 更新状态,保留默认选项 setFornecedoresOptions([ { value: "", text: "Escolha uma opção" }, ...newOptions ]); };
2. 动态渲染IonSelect选项
把之前的静态选项替换为动态渲染的状态数据:
<IonItem> <IonLabel position="stacked">Fornecedores</IonLabel> <IonSelect interface="popover" value=""> {fornecedoresOptions.map(option => ( <IonSelectOption key={option.value} value={option.value} className="brown-option" > {option.text} </IonSelectOption> ))} </IonSelect> </IonItem>
这样,当请求成功获取XML数据后,组件会自动重新渲染,把供应商选项填充到IonSelect里。
内容的提问来源于stack exchange,提问作者Inês Borges
相关产品推荐
相关产品推荐

