You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.02 11:55:43