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

Node.js API开发问题:表单提交响应展示与重复提交实现

问题解决与代码修复

1. 修复SyntaxError: Unexpected end of input

你的代码存在多处语法缺失与冲突问题:

  • app.post回调函数未闭合,缺少});
  • fetch调用仅添加了then回调,未补充错误处理与闭合括号
  • then回调的参数res与app.post的响应对象重名,导致变量冲突
  • responseHTML仅在app.get中定义,app.post中未声明就使用

2. 实现表单提交响应展示与重复提交功能

采用前端异步提交(AJAX)方案,避免页面刷新,同时保留所有提交记录:

修改后的完整代码

const fetch = require('node-fetch');
const express = require('express');
const app = express();

// 解析请求体
app.use(express.json());
app.use(express.urlencoded({ extended: true }));

// 渲染主页面(包含表单与前端交互逻辑)
app.get('/', (req, res) => {
  const html = `
    <html>
      <body>
        <h1>Login Form</h1>
        <form id="loginForm">
          <label for="csrf_token">CSRF Token:</label> 
          <input type="text" name="csrf_token" id="csrf_token" required><br>   
          
          <label for="email">Email:</label>  
          <input type="email" name="email" id="email" required><br>
          
          <label for="password">Password:</label>  
          <input type="password" name="password" id="password" required><br>
          
          <button type="submit">Submit</button>
        </form>
        <div id="responsesContainer">
          <h2>Submission Responses:</h2>
        </div>
        <script>
          const form = document.getElementById('loginForm');
          const responsesContainer = document.getElementById('responsesContainer');
          
          form.addEventListener('submit', async (e) => {
            e.preventDefault(); // 阻止页面刷新
            const formData = new FormData(form);
            const data = Object.fromEntries(formData);
            
            try {
              const response = await fetch('/submit', {
                method: 'POST',
                headers: {
                  'Content-Type': 'application/json',
                },
                body: JSON.stringify(data),
              });
              
              const result = await response.json();
              // 创建新元素展示响应
              const responseElement = document.createElement('pre');
              responseElement.textContent = JSON.stringify(result, null, 2);
              responsesContainer.appendChild(responseElement);
              // 重置表单
              form.reset();
            } catch (err) {
              const errorElement = document.createElement('div');
              errorElement.style.color = 'red';
              errorElement.textContent = \`Error: \${err.message}\`;
              responsesContainer.appendChild(errorElement);
            }
          });
        </script>
      </body>
    </html>
  `;
  res.send(html);
});

// 处理表单提交的API接口
app.post('/submit', async (req, res) => {
  try {
    const { csrf_token, email, password } = req.body;

    // 构造请求 payload(直接用对象而非字符串拼接,避免语法错误)
    const payload = {
      "_csrf_token": csrf_token,
      "email": email,
      "grant_type": "PWD",
      "page": "AccountLogin",
      "password": password,
      "recaptchaResponse": null,
      "recaptchaSiteKey": null,
      "step": "password",
      "userDefaultedToPassword": false
    };

    const apiResponse = await fetch('https://scrapeninja.p.rapidapi.com/scrape', {
      method: 'POST',
      headers: {
        "Content-Type": "application/json",
        "x-rapidapi-host": "HIDDEN",
        "x-rapidapi-key": "HIDDEN"
      },
      body: JSON.stringify({
        "url": "https://www.wayfair.com/a/account/authentication/login",
        "method": "POST",
        "headers": [
          "authority: www.wayfair.com",
          "accept: application/json",
          "accept-language: en-US,en;q=0.9,ar;q=0.8",
          "content-type: application/json",
          "cookie: WFDC=DSM; CSNUtId=412864fc-a9f8-405c-8e19-aa56c086d7ea; ExCSNUtId=412864fc-a9f8-405c-8e19-aa56c086d7ea; vid=23e17d3a-64a8-81d9-9e3c-5c0227712302; SFSID=ed904601ed2bb197bcbf8d4f7643e8cc; canary=0; serverUAInfo=%7B%22browser%22%3A%22Google%20Chrome%22%2C%22browserVersion%22%3A114%2C%22OS%22%3A%22Windows%22%2C%22OSVersion%22%3A%2210%22%2C%22isMobile%22%3Afalse%2C%22isTablet%22%3Afalse%2C%22isTouch%22%3Afalse%7D; __px_jnfwwtr_5=disable; _pxhd=bytlkNG5QrgGWPC-1RImOXynN/cLl26bEP24UXFCHXT4He3u0Wh/mg3ui2mytf2n27lyNOZ85vc-lS7T36UIWw==:eLUfj4aK5RXvvmjDlAlCh8zSBU-3GpStZIT2o40y1HojI1D3p7xCH/aXJfZGO9TizTXeUiEBw5yVXmJFLaHL8fQYbI6z3V8rtEWJuu6zneo=; CSN_CSRF=c60cafb9043d3d61febb81a38d23ece011ecf59df63774332d8a1be0c401fe52; __cf_bm=OYuVFxcPmLDoUgBGpP7Nj78NQm5R.Jr7cK8ggEIR3Wo-1688764889-0-AejgIZQcufTBjfmr47Oi/soHVUy7JtWjQ0r9cSXFy8T+Rznig68CKCwIFVNcjBEv3llV7a66LjzOq8HiB9IQIac=; CSN=g_countryCode%3DUS%26g_zip%3D67346; CSNPersist=page_of_visit%3D5; _wf_fs_sample_user=true; ibb=1; CSNID=FCD55A66-8513-46C7-A656-C2C65BB20149; WFCS=CS9; g_state={\"i_p\":1688772129177,\"i_l\":1}; hideGoogleYolo=true",
          "origin: https://www.wayfair.com",
          "referer: https://www.wayfair.com/v/account/authentication/login?url=https%3A%2F%2Fwww.wayfair.com%2F&amp;context=header_wayfair_my_account_menu",
          "sec-ch-ua: \"Not.A/Brand\";v=\"8\", \"Chromium\";v=\"114\", \"Microsoft Edge\";v=\"114\"",
          "sec-ch-ua-mobile: ?0",
          "sec-ch-ua-platform: \"Windows\"",
          "sec-fetch-dest: empty",
          "sec-fetch-mode: cors",
          "sec-fetch-site: same-origin",
          "sec-gpc: 1",
          "user-agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36 Edg/114.0.1823.67",
          "x-auth-caller-context: auth_main_page_context",
          "x-csn-csrf-token: c60cafb9043d3d61febb81a38d23ece011ecf59df63774332d8a1be0c401fe52",
          "x-parent-txid: I+F9OmSoge50vzFQLI6HAg==",
          "x-requested-with: XMLHttpRequest"
        ],
        "data": payload
      })
    });

    const result = await apiResponse.json();
    res.json(result);
  } catch (err) {
    res.status(500).json({ error: err.message });
  }
});

app.listen(3000, () => {
  console.log('Server running on port 3000');
});

方案说明

  • 语法修复:补充所有缺失的闭合括号,重命名冲突变量,添加错误捕获逻辑
  • 响应展示:前端通过AJAX异步提交表单,将后端返回的JSON结果追加到页面下方的容器中,无需刷新页面
  • 重复提交:提交完成后自动重置表单,每次提交的响应都会保留在页面上,实现多次提交的需求

内容的提问来源于stack exchange,提问作者John Holk

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.16 20:47:31