如何从服务器获取文本文件内容并制表?代码故障排查求助
你的代码问题排查与修复
我帮你梳理出几个核心问题,这些问题导致你的代码无法正常加载文件并生成表格:
关键问题分析
- XHR事件处理逻辑完全混乱:你把
onreadystatechange的绑定注释掉了,还在发送请求之前就判断readyState和status,这根本不符合AJAX的执行流程——必须先绑定事件处理函数,再发送请求,等待请求完成后触发回调处理数据。 - 变量作用域错误:
tableObj、responseText这些变量被定义在错误的作用域里,导致convert、filterRows等函数无法访问它们,会直接抛出未定义的错误。 - 数据分隔符选择不当:你用单个空格作为单元格分隔符,但目标文件里的内容是用多个空格分隔字段的,直接用单个空格拆分会把一个字段拆成多个单元格(比如
NUL (null)会被拆成NUL、(null))。 - 函数调用时机错误:你在发送请求前就调用了
convert(responseText),这时候请求还没发起,responseText根本不存在。
修复后的完整代码
<!DOCTYPE html> <html> <meta charset="UTF-8"> <head> <style type="text/css"> body { font-family: Arial; font-size: 10pt; } table { border: 1px solid #ccc; margin: auto; empty-cells: hide; } table th { background-color: AQUA; color: #333; font-weight: bold; } table th, table td { padding: 5px; border: 1px solid #ccc; border-color: #ccc; } tr:hover {background-color: #f5f5f5;} </style> </head> <body> <div align = center> <input type="text" id="filter" placeholder="Search" title="Type a name" > </div> <div id="demo" align = center> </div> <script> window.onload = function() { var demo = document.getElementById("demo"); var tableObj = { headers: ["Hex", "Abbr", "Description"], rows: [] }; const ROW_DELIMITER = "\n", CELL_DELIMITER = /\s{2,}/; // 用连续空格作为分隔符 // 初始化XHR对象 var xhttp; if(window.XMLHttpRequest){ xhttp = new XMLHttpRequest(); } else { xhttp = new ActiveXObject("Microsoft.XMLHTTP"); } // 绑定请求完成后的回调函数 xhttp.onreadystatechange = function() { if (this.readyState == 4 && (this.status == 200 || this.status == 0)) { var responseText = this.responseText; // 过滤掉空行和开头的注释行 const filteredText = responseText.split(ROW_DELIMITER) .filter(line => line.trim() !== "" && !line.startsWith("#")) .join(ROW_DELIMITER); convert(filteredText); // 绑定搜索事件 document.getElementById("filter").onkeyup = filterRows; } }; function convert(responseText) { tableObj.rows = convertToArray(responseText); buildTable(tableObj.headers, tableObj.rows); }; function convertToArray(text) { return text.split(ROW_DELIMITER).map(function(row) { // 用连续空格拆分,同时去掉首尾空格 return row.trim().split(CELL_DELIMITER); }); } function filterRows() { var input = this; var rows = tableObj.rows.filter(function(row) { var matches = row.filter(function(cell) { return cell.toUpperCase().indexOf(input.value.toUpperCase()) > -1; }); return matches.length > 0; }); buildTable(tableObj.headers, rows); } function sortRows() { var th = this; var index = th.dataset.index; tableObj.rows.sort(function(rowA, rowB) { var textA = rowA[index].toUpperCase(), textB = rowB[index].toUpperCase(); if (textA < textB) { return -1; } if (textA > textB) { return 1; } return 0; }); buildTable(tableObj.headers, tableObj.rows); } function buildTable(headers, rows) { var table = document.createElement('table'); var tr = document.createElement('tr'); table.appendChild(tr); for (var i = 0; i < headers.length; i++) { var th = document.createElement('th'); tr.appendChild(th); th.innerHTML = headers[i]; th.onclick = sortRows; th.dataset.index = i; } for (var j = 0; j < rows.length; j++) { tr = document.createElement('tr'); table.appendChild(tr); for (var k = 0; k < rows[j].length; k++) { var td = document.createElement('td'); tr.appendChild(td); td.innerHTML = rows[j][k]; td.dataset.index = k; } } demo.innerHTML = ''; demo.appendChild(table); } // 最后发送请求 xhttp.open("GET", "https://www.w3.org/TR/PNG/iso_8859-1.txt", true); xhttp.send(null); }; </script> </body> </html>
主要修改说明
- 调整XHR执行流程:先绑定
onreadystatechange回调,再调用open和send,确保请求完成后能触发数据处理逻辑。 - 修正变量作用域:把
tableObj、ROW_DELIMITER等变量提升到全局(相对于window.onload的作用域),让所有函数都能访问到。 - 优化数据分隔逻辑:用正则表达式
/\s{2,}/匹配连续空格作为单元格分隔符,避免单个空格拆分字段;同时过滤掉文件里的空行和注释行,让表格更整洁。 - 修正函数调用时机:只在XHR请求成功拿到数据后,才调用
convert函数处理文本。 - 调整表头:根据目标文件的内容(十六进制、缩写、描述)修改了表头,更贴合实际数据。
内容的提问来源于stack exchange,提问作者Sumanth
相关产品推荐
相关产品推荐

