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&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
相关产品推荐
相关产品推荐

