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

如何实现HTML表单调用同目录Python脚本并展示GPT响应?

问题解决与代码修改方案

核心问题分析

当前代码的关键冲突在于:Node.js通过命令行参数传递用户输入,但Python脚本却按照CGI表单的方式读取参数,两者的参数传递机制不匹配,导致Python无法获取到用户输入。此外还有几个次要问题:Python每次运行都重复安装openai包、Node.js错误时未向客户端返回响应、缺少必要的错误处理逻辑。


各文件修改后的代码(带注释)

1. Python脚本 algo.py

import sys
import json
import openai
from openai import OpenAI

# 移除重复安装openai的代码,建议提前手动执行:pip install openai
# 避免每次运行脚本都重新安装,浪费资源

# 配置OpenAI API密钥
client = OpenAI(
    api_key='你的API密钥',  # 替换为实际密钥
)

def AI_PC_Buddy(prompt):
    messages = [{'role': 'user', 'content': prompt}]
    
    response = client.chat.completions.create(
        model='gpt-3.5-turbo',
        messages=messages
    )
    return response.choices[0].message.content.strip()

if __name__ == "__main__":
    # 从命令行参数获取用户输入(Node.js传递的参数)
    # sys.argv[0]是脚本名,sys.argv[1]是第一个参数
    if len(sys.argv) < 2:
        # 没有输入时返回错误信息
        print(json.dumps({'response': '错误:未收到用户输入'}))
        sys.exit(1)
    
    prompt = sys.argv[1]
    try:
        response = AI_PC_Buddy(prompt)
        # 返回JSON格式的响应,和前端预期一致
        print(json.dumps({'response': response}))
    except Exception as e:
        # 捕获OpenAI调用或其他异常,返回错误信息
        print(json.dumps({'response': f'服务出错:{str(e)}'}))

2. Node.js服务器 server.js

const express = require('express');
const { execFile } = require('child_process'); // 改用execFile更安全,避免命令注入

const app = express();
const port = 8005;

// 解析JSON请求体,前端发送的是JSON格式
app.use(express.json());

// 处理静态文件(如果需要直接访问HTML文件)
app.use(express.static('.')); // 假设HTML文件和server.js在同一目录

// 处理执行脚本的POST请求
app.post('/execute_script', (req, res) => {
    const userInput = req.body.prompt;
    
    // 校验输入是否为空
    if (!userInput.trim()) {
        return res.status(400).json({'response': '请输入有效内容'});
    }

    // 用execFile执行Python脚本,参数数组传递输入,避免命令注入和特殊字符问题
    execFile('python3', ['algo.py', userInput], (error, stdout, stderr) => {
        if (error) {
            console.error('执行Python脚本失败:', error.message);
            return res.status(500).json({'response': '服务器执行脚本出错'});
        }
        if (stderr) {
            console.error('Python脚本内部错误:', stderr);
            return res.status(500).json({'response': '脚本处理出错'});
        }
        try {
            // 解析Python输出的JSON字符串
            const result = JSON.parse(stdout);
            res.json(result);
        } catch (parseError) {
            console.error('解析Python响应失败:', parseError.message);
            res.status(500).json({'response': '响应解析出错'});
        }
    });
});

// 启动服务器
app.listen(port, () => {
    console.log(`服务器运行在 http://localhost:${port}`);
});

3. HTML文件(补充必要元素)

<!-- 确保添加展示结果的div -->
<div id="responseContainer" style="margin-top: 20px; padding: 10px; border: 1px solid #eee;"></div>

<!-- SEARCH FORM  -->
<form id="searchform" onsubmit="submitForm(event)">
    <div class="search">
        <span class="search-icon material-symbols-outlined">search</span>
        <input id="searchinput" class="search-input" type="search" placeholder="What did you want to build? ">
        <button type="submit">Generate</button>
    </div>
</form>

<script>
    function submitForm(event) {
        event.preventDefault();
        
        const userInput = document.getElementById("searchinput").value.trim();
        const responseContainer = document.getElementById("responseContainer");
        
        // 清空之前的结果并显示加载状态
        responseContainer.innerHTML = "<p>正在生成响应...</p>";
        
        if (!userInput) {
            responseContainer.innerHTML = "<p>请输入有效内容</p>";
            return;
        }
        
        fetch('/execute_script', {
            method: 'POST',
            headers: {
                'Content-Type': 'application/json',
            },
            body: JSON.stringify({ prompt: userInput }),
        })
        .then(response => {
            if (!response.ok) {
                throw new Error('服务器响应异常');
            }
            return response.json();
        })
        .then(data => {
            // 展示结果,转义HTML特殊字符避免XSS
            const safeContent = document.createElement('p');
            safeContent.textContent = data.response;
            responseContainer.innerHTML = '';
            responseContainer.appendChild(safeContent);
            // 清空输入框
            document.getElementById("searchinput").value = '';
        })
        .catch(error => {
            console.error('请求出错:', error);
            responseContainer.innerHTML = "<p>请求失败,请稍后重试</p>";
        });
    }
</script>

修改思路说明

  1. 参数传递机制统一:

    • 放弃Python的CGI方式,改用命令行参数接收Node.js传递的用户输入,两者机制匹配,解决核心的参数传递失败问题。
    • 使用execFile替代exec,通过参数数组传递输入,避免字符串拼接导致的命令注入风险,同时兼容包含空格、引号的用户输入。
  2. 优化性能与稳定性:

    • 移除Python中每次运行都安装openai的代码,改为提前手动安装,避免重复安装的资源浪费。
    • 增加输入校验(前端+后端),避免空请求触发无效的API调用。
    • 完善错误处理:前端显示加载状态、错误提示;后端捕获执行错误、解析错误,并向客户端返回对应的错误响应,而不是静默失败。
  3. 安全性与用户体验:

    • 前端用textContent替代innerHTML直接拼接,避免XSS攻击。
    • 添加加载状态提示,清空输入框等细节,提升用户体验。

内容的提问来源于stack exchange,提问作者Hector Damian Reyes

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.25 05:11:38