为网站添加isapi扩展,清理大师,学网站设计培训电话,会员注册页面模板这个的后端代码参见此文
使用语言向量建立常见问题的模糊搜索-CSDN博客https://blog.csdn.net/chenchihwen/article/details/144207262?spm1001.2014.3001.5501 这段代码实现了一个简单的问答页面#xff0c;页面分为左右两部分#xff0c;左侧用于展示对话记录#xff0c…
这个的后端代码参见此文
使用语言向量建立常见问题的模糊搜索-CSDN博客https://blog.csdn.net/chenchihwen/article/details/144207262?spm1001.2014.3001.5501 这段代码实现了一个简单的问答页面页面分为左右两部分左侧用于展示对话记录右侧用于用户输入问题并提交获取答案后在对应区域显示答案同时会将每一轮的问答信息添加到对话记录中进行展示整体通过 HTML 结构定义页面布局结合 JavaScript 实现交互功能。
HTML 部分详细分析 文档结构与头部设置head部分 headmeta charsetUTF-8title问答测试/titlestyle...内联CSS样式后续单独分析/style
/head首先通过meta charsetUTF-8指定了文档的字符编码为 UTF-8确保能正确显示各种字符。title标签定义了页面的标题为 “问答测试”会显示在浏览器的标题栏。内联的style标签中定义了页面的样式规则用于控制页面元素的外观呈现。 页面主体结构body部分 bodydiv classmain-containerdiv classconversation-log-containerh2 classconversation-title对话记录/h2div idconversationDiv/div/divdiv classquestion-answer-containerh1 classqa-title提交问题与答案显示/h1form idquestionForm action/process_question methodpostlabel foruser_question请输入你的问题/labelbrinput typetext iduser_question nameuser_question requiredbrinput typesubmit value提交/formdiv idanswerDiv/div/div/div
/bodybody标签内是页面的主体内容整体采用了flex布局由外层的.main-container类样式控制将页面划分为左右两部分来展示不同的功能区域。左侧对话记录区域.conversation-log-container 包含一个h2标题标签显示 “对话记录” 字样用于提示该区域的作用。有一个空的div元素其id为conversationDiv后续通过 JavaScript 动态往里面添加对话记录的具体内容。右侧提交问题与答案显示区域.question-answer-container 首先有一个h1标题标签显示 “提交问题与答案显示”表明该区域功能。包含一个form表单元素其id为questionFormaction属性指向/process_question对应后端处理问题的接口和之前 Python 代码中的服务器路由相关联method属性为post表示以 POST 方式提交表单数据。表单内有一个label标签用于提示用户输入问题一个input文本框用于用户输入具体问题设置了required属性要求用户必须输入内容还有一个input提交按钮用于提交表单。还有一个空的div元素其id为answerDiv用于在提交问题后通过 JavaScript 获取后端返回的答案并展示在此处。
CSS 样式部分详细分析style内联样式 页面整体样式body选择器 body {font-family: Arial, sans-serif;background-color: #f4f4f4;display: flex;justify-content: center;align-items: center;min-height: 100vh;margin: 0;padding: 0;
}设置了页面整体的字体为Arial或无衬线字体sans-serif作为备选背景颜色为浅灰色#f4f4f4。利用flex布局将页面内容在水平和垂直方向上进行居中对齐设置最小高度为视口高度100vh并去除了页面默认的外边距和内边距。 主容器样式.main-container选择器 .main-container {display: flex;width: 1000px;
}定义了主容器采用flex布局宽度为1000px用于划分左右两部分的功能区域。 3. 左侧对话记录容器样式.conversation-log-container选择器 .conversation-log-container {background-color: #fff;padding: 20px;border-radius: 5px;box-shadow: 0 0 5px rgba(0, 0, 0, 0.1);width: 450px;/* height: 1000px; */
}将对话记录容器的背景色设置为白色#fff添加了内边距为20px设置了圆角边框半径为5px以及一个淡淡的阴影效果box-shadow属性使其在页面上有一定的立体感和视觉区分度。宽度设置为450px可以根据实际需求调整这个宽度值注释掉的height属性若启用可固定容器高度目前采用默认高度由内容撑开的方式。 对话记录标题样式h2.conversation-title选择器 h2.conversation-title {color: #333;
}设置对话记录标题的字体颜色为深灰色#333使其与整体页面风格协调且有一定的视觉层次。 5. 对话记录展示区域样式#conversationDiv选择器 #conversationDiv {margin-top: 20px;max-height: 450px;overflow-y: auto;font-family: Arial, sans-serif;
}给对话记录展示区域添加了顶部外边距为20px设置了最大高度为450px并当内容超出这个高度时启用垂直滚动条overflow-y: auto来查看更多对话记录内容字体同样遵循页面整体设置的Arial或无衬线字体风格。 对话记录单项样式.conversation-item选择器 .conversation-item {margin-bottom: 10px;padding: 10px;border-bottom: 1px solid #ccc;white-space: pre-line; /* 让对话记录中的内容也能折行显示 */
}
.conversation-item:last-child {border-bottom: none;
}每个对话记录单项有底部外边距为10px内边距为10px并且底部有一条浅灰色#ccc的边框用于区分不同的对话记录项最后一项通过:last-child伪类去除了底部边框使其视觉上更简洁。white-space: pre-line属性设置让对话记录中的文本内容可以按照正常的文本换行规则进行折行显示方便展示较长的问答内容。 问题文本样式.question选择器 .question {font-weight: bold;
}将对话记录中的问题文本设置为加粗字体便于区分问题和答案部分增强可读性。 8. 右侧提交问题与答案显示容器样式.question-answer-container选择器 .question-answer-container {background-color: #fff;padding: 20px;border-radius: 5px;box-shadow: 0 0 5px rgba(0, 0, 0, 0.1);width: 550px;margin-left: 50px;
}和左侧对话记录容器类似设置了白色背景、内边距、圆角边框、阴影效果等宽度设置为550px并且通过margin-left属性设置了与左侧容器的间距为50px使其在页面上合理布局。 9. 右侧标题样式h1.qa-title选择器 h1.qa-title {color: #333;
}设置右侧区域标题的字体颜色为深灰色#333保持页面整体视觉风格的一致性。 10. 表单样式form#questionForm选择器 form#questionForm {text-align: center;
}将表单内的元素在水平方向上进行居中对齐让页面布局看起来更整齐美观。 11. 标签样式label选择器 label {display: block;margin-bottom: 10px;
}使每个label标签单独占一行显示并设置了底部外边距为10px方便页面排版和阅读提示信息。 12. 输入框样式input[typetext]选择器 input[typetext] {width: 100%;padding: 10px;margin-bottom: 20px;border: 1px solid #ccc;border-radius: 3px;
}定义了文本输入框的样式宽度占满父容器100%添加了内边距为10px底部外边距为20px设置了浅灰色的边框以及较小的圆角边框效果使其外观简洁且符合常见的输入框设计风格。 13. 提交按钮样式input[typesubmit]选择器 input[typesubmit] {background-color: #007BFF;color: #fff;padding: 10px 20px;border: none;border-radius: 3px;cursor: pointer;
}将提交按钮的背景色设置为蓝色#007BFF常见的按钮强调色字体颜色为白色添加了内边距去除了边框设置了小的圆角边框效果并添加了鼠标指针悬停变为手型cursor: pointer的交互效果使其在页面上很容易被识别和操作。 14. 答案显示区域样式#answerDiv选择器 #answerDiv {white-space: pre-line;margin-top: 20px;word-break: break-all; /* 确保长文本能正常换行显示 */
}和对话记录展示区域类似设置了顶部外边距为20pxwhite-space: pre-line让内容可以按正常文本换行规则显示同时添加了word-break: break-all属性确保长文本能在合适的位置正常换行避免出现文本超出容器宽度而显示不全的情况。
JavaScript 部分详细分析 全局变量定义与表单提交事件监听 // 用于存储对话记录的数组
var conversation [];document.getElementById(questionForm).addEventListener(submit, function (e) {e.preventDefault();var questionInput document.getElementById(user_question);var questionText questionInput.value;var xhr new XMLHttpRequest();xhr.open(POST, /process_question, true);xhr.setRequestHeader(Content-Type, application/x-www-form-urlencoded);xhr.onreadystatechange function () {if (xhr.readyState 4 xhr.status 200) {var answerDiv document.getElementById(answerDiv);// 使用 innerHTML 将响应文本当作 HTML 内容解析使图片、超链接等能正确显示answerDiv.innerHTML xhr.responseText;// 将本次的问题和答案添加到对话记录数组中conversation.push({question: questionText,answer: xhr.responseText});// 清空输入框方便继续提问questionInput.value ;// 重新渲染对话记录展示区域renderConversation();}};xhr.send(user_question encodeURIComponent(questionText));
});首先定义了一个名为conversation的全局数组用于存储每一轮问答的信息问题和对应的答案。通过document.getElementById获取到页面中的表单元素并给其添加submit事件监听器。当用户提交表单时 调用e.preventDefault()阻止表单默认的提交行为避免页面刷新。获取用户在输入框中输入的问题文本内容。创建一个XMLHttpRequest对象用于发送 HTTP 请求到后端/process_question这个接口对应后端 Python 代码中处理问题的路由设置请求方式为POST并设置请求头的Content-Type为application/x-www-form-urlencoded。给xhr对象的onreadystatechange事件绑定回调函数当请求的状态变为4表示请求已完成且状态码为200表示成功时 获取页面中用于显示答案的div元素将后端返回的响应文本通过innerHTML属性赋值给该元素这样可以解析响应文本中的 HTML 内容比如如果答案中有图片、超链接等元素能正确显示。将本次的问题和答案以对象的形式添加到conversation数组中。清空输入框内容方便用户继续提问。调用renderConversation函数重新渲染对话记录展示区域使其能及时更新显示最新的问答信息。最后通过xhr.send方法发送包含用户问题的请求数据需要对问题文本进行encodeURIComponent编码以符合 URL 编码规范。 对话记录渲染函数renderConversation // 渲染对话记录展示区域的函数
function renderConversation() {var conversationDiv document.getElementById(conversationDiv);conversationDiv.innerHTML ;conversation.forEach(function (item, index) {var conversationItem document.createElement(div);conversationItem.className conversation-item;var questionDiv document.createElement(div);questionDiv.className question;questionDiv.innerHTML Q (index 1) : item.question;var answerDiv document.createElement(div);answerDiv.className answer;// 使用 innerHTML 将答案内容当作 HTML 内容解析使图片等能正确显示answerDiv.innerHTML A (index 1) : item.answer;conversationItem.appendChild(questionDiv);conversationItem.appendChild(answerDiv);conversationDiv.appendChild(conversationItem);});
}这个函数用于更新对话记录展示区域的内容首先获取到id为conversationDiv的元素并清空其原有的innerHTML内容。然后遍历conversation数组中的每一项每个问答对象 创建一个新的div元素作为对话记录单项的容器并设置其类名为conversation-item以应用对应的 CSS 样式。分别创建用于显示问题和答案的div子元素设置相应的类名question和answer并通过innerHTML将问答内容填充进去同样可以解析 HTML 内容。将问题和答案的div子元素添加到对话记录单项容器中再将该容器添加到对话记录展示区域的div元素内从而实现对话记录的动态渲染和展示。
潜在的改进点和注意事项 兼容性问题代码中使用的XMLHttpRequest在现代浏览器中基本都支持但对于一些较老版本的浏览器可能存在兼容性问题。可以考虑使用更现代的fetch API 来替代它提供了更简洁、功能更强大的异步请求方式并且有较好的浏览器兼容性不过需要进行适当的错误处理和功能适配。安全性考虑在将后端返回的内容直接通过innerHTML解析并显示时如果后端返回的数据不可信比如存在恶意的 HTML、JavaScript 代码可能会导致安全漏洞如跨站脚本攻击XSS。建议对后端返回的数据进行严格的过滤和转义处理只允许显示安全的文本内容或者对 HTML 标签进行白名单验证后再进行解析显示。响应数据格式处理优化目前假设后端返回的文本可以直接通过innerHTML进行解析显示但如果后端返回的数据格式比较复杂比如是 JSON 格式包含了多种类型的数据需要分别处理需要进一步优化代码逻辑对响应数据进行准确的解析和展示例如可以通过JSON.parse先将 JSON 数据解析成 JavaScript 对象再根据具体的结构进行相应的页面渲染操作。
完整代码如下 !DOCTYPE html
html langenheadmeta charsetUTF-8title问答测试/titlestylebody {font-family: Arial, sans-serif;background-color: #f4f4f4;display: flex;justify-content: center;align-items: center;min-height: 100vh;margin: 0;padding: 0;}.main-container {display: flex;width: 1000px;}/* 左侧对话记录样式 */.conversation-log-container {background-color: #fff;padding: 20px;border-radius: 5px;box-shadow: 0 0 5px rgba(0, 0, 0, 0.1);width: 450px;/* height: 1000px; */}h2.conversation-title {color: #333;}#conversationDiv {margin-top: 20px;max-height: 450px;overflow-y: auto;font-family: Arial, sans-serif;}.conversation-item {margin-bottom: 10px;padding: 10px;border-bottom: 1px solid #ccc;white-space: pre-line; /* 让对话记录中的内容也能折行显示 */}.conversation-item:last-child {border-bottom: none;}.question {font-weight: bold;}/* 右侧提交问题和答案显示样式 */.question-answer-container {background-color: #fff;padding: 20px;border-radius: 5px;box-shadow: 0 0 5px rgba(0, 0, 0, 0.1);width: 550px;margin-left: 50px;}h1.qa-title {color: #333;}form#questionForm {text-align: center;}label {display: block;margin-bottom: 10px;}input[typetext] {width: 100%;padding: 10px;margin-bottom: 20px;border: 1px solid #ccc;border-radius: 3px;}input[typesubmit] {background-color: #007BFF;color: #fff;padding: 10px 20px;border: none;border-radius: 3px;cursor: pointer;}#answerDiv {white-space: pre-line;margin-top: 20px;word-break: break-all; /* 确保长文本能正常换行显示 */}/style
/headbodydiv classmain-containerdiv classconversation-log-containerh2 classconversation-title对话记录/h2div idconversationDiv/div/divdiv classquestion-answer-containerh1 classqa-title提交问题与答案显示/h1form idquestionForm action/process_question methodpostlabel foruser_question请输入你的问题/labelbrinput typetext iduser_question nameuser_question requiredbrinput typesubmit value提交/formdiv idanswerDiv/div/div/divscript// 用于存储对话记录的数组var conversation [];document.getElementById(questionForm).addEventListener(submit, function (e) {e.preventDefault();var questionInput document.getElementById(user_question);var questionText questionInput.value;var xhr new XMLHttpRequest();xhr.open(POST, /process_question, true);xhr.setRequestHeader(Content-Type, application/x-www-form-urlencoded);xhr.onreadystatechange function () {if (xhr.readyState 4 xhr.status 200) {var answerDiv document.getElementById(answerDiv);// 使用 innerHTML 将响应文本当作 HTML 内容解析使图片、超链接等能正确显示answerDiv.innerHTML xhr.responseText;// 将本次的问题和答案添加到对话记录数组中conversation.push({question: questionText,answer: xhr.responseText});// 清空输入框方便继续提问questionInput.value ;// 重新渲染对话记录展示区域renderConversation();}};xhr.send(user_question encodeURIComponent(questionText));});// 渲染对话记录展示区域的函数function renderConversation() {var conversationDiv document.getElementById(conversationDiv);conversationDiv.innerHTML ;conversation.forEach(function (item, index) {var conversationItem document.createElement(div);conversationItem.className conversation-item;var questionDiv document.createElement(div);questionDiv.className question;questionDiv.innerHTML Q (index 1) : item.question;var answerDiv document.createElement(div);answerDiv.className answer;// 使用 innerHTML 将答案内容当作 HTML 内容解析使图片等能正确显示answerDiv.innerHTML A (index 1) : item.answer;conversationItem.appendChild(questionDiv);conversationItem.appendChild(answerDiv);conversationDiv.appendChild(conversationItem);});}/script/body/html