Flask项目中无法用JavaScript为文本添加下划线的问题排查
Flask后端返回结果后,前端无法给用户输入文本添加下划线
问题描述
我正在开发一个Flask项目,需要根据服务器返回的响应为用户输入中的特定文本添加下划线。项目采用Flask作为后端,JavaScript作为前端。
Flask后端代码
@app.route('/text', methods=['POST']) def text(): user_text = request.form['user_input'] payload = { "providers": "cohere", "language": "en", "text": user_text, "fallback_providers": "", } response = requests.post(url2, json=payload, headers=headers) result = json.loads(response.text) res = result['cohere']['items'] return jsonify(text=res)
前端JavaScript代码
fetch('/text', { method: 'POST', body: formData, }) .then((response) => response.json()) .then((data) => { let text = data.text; console.log("Extracted Text:", text); text.forEach((item) => { if (item.type === "error") { let regex = new RegExp(`\\b${item.text}\\b`, "g"); userInputInput.innerHTML = userInputInput.innerHTML.replace(regex, `<span style="text-decoration: underline;">${item.text}</span>`); } }); }) .catch((error) => { console.error("Error fetching response:", error); });
控制台能正常打印返回结果,但页面上的目标文本并未显示下划线,求问题原因分析及解决建议。
问题原因分析
- 正则匹配失效:使用
\b单词边界时,若目标文本包含非单词字符(如标点、特殊符号)或正则元字符(如.、$),会导致匹配失败,无法触发替换。 - 表单元素限制:如果
userInputInput是<input>或<textarea>,这类元素仅支持纯文本内容,设置innerHTML无法解析HTML标签,自然不会显示下划线样式。 - 重复替换破坏结构:每次循环直接修改
innerHTML,会导致已添加<span>的文本被重复匹配,甚至破坏HTML结构,导致样式不生效。
解决建议
1. 修复正则表达式匹配逻辑
先转义目标文本中的正则特殊字符,避免元字符干扰,同时根据需求调整单词边界:
// 转义正则特殊字符的工具函数 function escapeRegExp(string) { return string.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'); } // 替换逻辑优化 text.forEach((item) => { if (item.type === "error") { const escapedText = escapeRegExp(item.text); // 若目标文本含特殊字符,可去掉\b改为精确匹配或调整边界规则 const regex = new RegExp(`\\b${escapedText}\\b`, "g"); // 基于原始文本替换,避免重复修改DOM const originalContent = userInputInput.textContent || userInputInput.value; const newContent = originalContent.replace(regex, `<span style="text-decoration: underline;">${item.text}</span>`); // 根据元素类型设置内容 if (['INPUT', 'TEXTAREA'].includes(userInputInput.tagName)) { // 表单元素不支持HTML,替换为可编辑div userInputInput.outerHTML = `<div contenteditable="true">${newContent}</div>`; } else { userInputInput.innerHTML = newContent; } } });
2. 使用支持HTML渲染的元素
将<input>或<textarea>替换为<div contenteditable="true">,这类元素可以直接解析HTML标签,完美渲染下划线样式。
3. 基于原始文本批量替换
发送请求前保存用户输入的原始文本,基于原始文本完成所有替换后再更新DOM,避免重复修改导致的结构问题:
// 提前保存原始输入文本 const originalInput = userInputInput.value || userInputInput.textContent; fetch('/text', { method: 'POST', body: formData, }) .then((response) => response.json()) .then((data) => { let displayContent = originalInput; data.text.forEach((item) => { if (item.type === "error") { const escapedText = escapeRegExp(item.text); const regex = new RegExp(`\\b${escapedText}\\b`, "g"); displayContent = displayContent.replace(regex, `<span style="text-decoration: underline;">${item.text}</span>`); } }); // 更新DOM if (['INPUT', 'TEXTAREA'].includes(userInputInput.tagName)) { userInputInput.outerHTML = `<div contenteditable="true">${displayContent}</div>`; } else { userInputInput.innerHTML = displayContent; } }) .catch((error) => { console.error("Error fetching response:", error); });
内容的提问来源于stack exchange,提问作者dnrksd
相关产品推荐
相关产品推荐

