为何控制台返回JSON解析错误,无法将表单数据同步至Mailchimp列表?
问题:提交数据到Mailchimp列表时出现JSON解析错误
我尝试用自制表单提交数据到Mailchimp列表,用body-parser解析表单数据后构造符合Mailchimp批量订阅API格式的JSON,再通过Node.js的https模块发送POST请求。修正request.end为request.end()后,控制台抛出JSON解析错误,且Mailchimp列表里的用户合并字段为空。
原代码
app.post("/",function(req,res){ const fName = req.body.first_name; const lName = req.body.last_name; const email = req.body.email; const data = { members: [ { email_address: email, status: "subscribed", merge_fields: { first_name: fName, last_name: lName } } ] } const jsonData = JSON.stringify(data); const url = "https://{api-server}.api.mailchimp.com/3.0/lists/{list_id}"; const options = { method:"POST", auth: "{my_string}:{my_api_key}" } const request = https.request(url, options, function(response){ response.on("data",function(data){ console.log(JSON.parse(data)); }) }) request.write(jsonData); request.end(); })
出现的错误
undefined:1 {"new_members":[{"id":"2f0285dfb0337da7ddbc581a5452fd06","email_address":"buchu@luyu.com","unique_email_id":"5b4586e19a","email_type":"html","status":"subscribed","merge_fields":{"FNAME":"","LNAME":"","ADDRESS":"","PHONE":"","BIRTHDAY":""},"stats":{"avg_open_rate":0,"avg_click_rate":0},"ip_signup":"","timestamp_signup":"","ip_opt":"202.51.69.32","timestamp_opt":"2023-12-09T06:40:27+00:00","member_rating":2,"last_changed":"2023-12-09T06:40:27+00:00","language":"","vip":false,"email_client":"","location":{"latitude":0,"longitude":0,"gmtoff":0,"dstoff":0,"country_code":"","timezone":""},"tags_count":0,"tags":[],"list_id":"bd9a1eb732","_links":[{"rel":"self","href":"https://us21.api.mailchimp.com/3.0/lists/{my_list_id}/members/2f0285dfb0337da7ddbc581a5452fd06","method":"GET","targetSchema":"https://us21.api.mailchimp.com/schema/3.0/Definitions/Lists/Members/Response.json"},{"rel":"parent","href":"https://us21.api.mailchimp.com/3.0/lists/{my_list_id}/members","method":"GET","targetSchema":"https://us21.api.mailchimp.com/schema/3.0/Definitions/Lists/Members/CollectionResponse.json","schema":"https://us21.api.mailchimp.com/schema/3.0/Paths/Lists/Members/Collection.json"},{"rel":"update","href":"https://us21.api.mailchimp.com/3.0/lists/{my_list_id}/members/2f0285dfb0337da7ddbc581a5452fd06","method":"PATCH","targetSchema":"https://us21.api.mailchimp.com/schema/3.0 SyntaxError: Unterminated string in JSON at position 1371 at JSON.parse (<anonymous>) at IncomingMessage.<anonymous> (F:\Projects\newsletter-signup\app.js:56:30) at IncomingMessage.emit (node:events:514:28) at Readable.read (node:internal/streams/readable:758:10) at flow (node:internal/streams/readable:1248:53) at resume_ (node:internal/streams/readable:1227:3) at process.processTicksAndRejections (node:internal/process/task_queues:82:21)
解决方案
1. 修复响应数据分段解析问题
Node.js的IncomingMessage的data事件会分多次返回响应内容,直接解析单块数据会导致JSON不完整。需要先拼接所有数据块,在end事件触发后再解析:
const request = https.request(url, options, function(response){ let responseData = ''; // 拼接所有数据块 response.on("data",function(chunk){ responseData += chunk; }); // 数据接收完成后解析 response.on("end", function(){ try { const result = JSON.parse(responseData); console.log(result); // 根据返回结果给前端响应 if(result.new_members){ res.send("订阅成功"); } else { res.send("订阅失败:" + result.title); } } catch (err) { console.error("JSON解析错误:", err); res.send("服务器处理错误"); } }); })
2. 修正Mailchimp合并字段名称
从错误返回的merge_fields可以看到,Mailchimp使用的是FNAME和LNAME(大写),而代码里用的是first_name和last_name,导致字段值无法正确传入。需要修改合并字段的键名:
merge_fields: { FNAME: fName, LNAME: lName }
3. 验证API端点配置
确认url中的{api-server}(比如返回结果里的us21)和{list_id}(比如返回结果里的bd9a1eb732)是否与你的Mailchimp账户信息匹配,替换成实际值。
修正后的完整代码
app.post("/",function(req,res){ const fName = req.body.first_name; const lName = req.body.last_name; const email = req.body.email; const data = { members: [ { email_address: email, status: "subscribed", merge_fields: { FNAME: fName, LNAME: lName } } ] } const jsonData = JSON.stringify(data); // 替换为实际的api服务器和列表ID const url = "https://us21.api.mailchimp.com/3.0/lists/bd9a1eb732"; const options = { method:"POST", auth: "my_string:my_api_key" // 替换为实际的认证信息 } const request = https.request(url, options, function(response){ let responseData = ''; response.on("data",function(chunk){ responseData += chunk; }); response.on("end", function(){ try { const result = JSON.parse(responseData); console.log(result); if(result.new_members && result.new_members.length > 0){ res.send("订阅成功!"); } else { res.send(`订阅失败:${result.detail || "未知错误"}`); } } catch (err) { console.error("解析响应失败:", err); res.send("服务器处理错误"); } }); // 监听请求错误 response.on("error", function(err){ console.error("请求错误:", err); res.send("请求失败"); }); }) // 监听请求写入错误 request.on("error", function(err){ console.error("发送请求错误:", err); res.send("发送请求失败"); }); request.write(jsonData); request.end(); })
内容的提问来源于stack exchange,提问作者ch_40x
相关产品推荐
相关产品推荐

