使用Heroku CORS Anywhere代理后表单无法发送消息如何解决?
解决Blogger联系表单跨域提交失败问题
我使用Heroku CORS Anywhere代理解决表单的CORS Access-Control-Allow-Origin跨域问题,但现在每次尝试发送消息时,表单均提示消息未发送,请求协助解决。
我的表单: Demo页面
原脚本代码:
const blogId="xxxxxxxxxxxxx"; var contactForm = document.querySelectorAll(".contact-form-blogger"); function an(req) { try { return JSON.parse(req) } catch (req) { return false } } for (i = 0; i < contactForm.length; i++) { var a = contactForm[i]; a.addEventListener("submit", function (submitUrl) { submitUrl.preventDefault(); var form = submitUrl.target; var req = new FormData(form), cH = "blogID=" + typeof blogId !== "undefined" ? blogId : ""; req.forEach(function (cL, cK) { cH += "&" + encodeURIComponent(cK) + "=" + encodeURIComponent(cL) }); submitUrl = "https://cors-anywhere.herokuapp.com/https://www.blogger.com/contact-form.do"; req = new XMLHttpRequest; req.open("post", submitUrl, true); req.setRequestHeader("Content-Type", "application/x-www-form-urlencoded"); req.send(cH); req.onreadystatechange = function () { var cK; if (this.readyState === 4) { if (this.status === 200) { if (this.response != "") { cK = an(this.responseText.trim()); if (cK.details.emailSentStatus == "true") { form.reset(); var formSend = form.querySelector(".send-success"); if (formSend) { formSend.style.display = "block"; } } else { var notSend = form.querySelector(".send-error"); if (notSend) { notSend.style.display = "block"; } } } } } } }) }
问题排查与修复方案
1. 修复三元运算符优先级错误
原代码中拼接blogID的语句存在优先级逻辑错误:
cH = "blogID=" + typeof blogId !== "undefined" ? blogId : "";
+运算符优先级高于!==,导致实际执行逻辑是("blogID=" + typeof blogId) !== "undefined",会造成blogID参数拼接异常。修正为:
cH = "blogID=" + (typeof blogId !== "undefined" ? blogId : "");
2. 调试响应内容,确认返回格式
在请求回调中添加调试日志,查看Blogger接口返回的实际内容,判断是否为预期的JSON格式:
req.onreadystatechange = function () { var cK; if (this.readyState === 4) { console.log("状态码:", this.status); console.log("响应内容:", this.responseText); // 新增调试日志 if (this.status === 200) { if (this.response != "") { cK = an(this.responseText.trim()); console.log("解析结果:", cK); // 新增调试日志 // ... 后续逻辑 } } } }
如果解析失败(cK为false),说明返回内容不是标准JSON,需要调整解析逻辑。
3. 处理CORS Anywhere公共实例限制
Heroku上的公共CORS Anywhere实例有访问频率限制,且首次访问需要手动授权。建议:
- 自行部署私有CORS Anywhere实例,避免公共实例的限流问题
- 先在浏览器中访问CORS Anywhere域名,点击授权按钮获取临时访问权限后再测试表单
4. 添加必要的请求头
Blogger联系表单接口可能验证Referer头,模拟真实请求来源:
req.setRequestHeader("Referer", window.location.href);
修正后的完整脚本
const blogId="xxxxxxxxxxxxx"; var contactForm = document.querySelectorAll(".contact-form-blogger"); function parseResponse(req) { try { return JSON.parse(req) } catch (e) { console.error("响应解析失败:", e); return false } } for (let i = 0; i < contactForm.length; i++) { const form = contactForm[i]; form.addEventListener("submit", function (e) { e.preventDefault(); const formData = new FormData(form); // 修复三元运算符优先级 let params = "blogID=" + (typeof blogId !== "undefined" ? blogId : ""); formData.forEach(function (value, key) { params += "&" + encodeURIComponent(key) + "=" + encodeURIComponent(value) }); const submitUrl = "https://cors-anywhere.herokuapp.com/https://www.blogger.com/contact-form.do"; const xhr = new XMLHttpRequest; xhr.open("POST", submitUrl, true); xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded"); // 添加Referer头 xhr.setRequestHeader("Referer", window.location.href); xhr.send(params); xhr.onreadystatechange = function () { if (this.readyState === 4) { console.log("状态码:", this.status); console.log("响应内容:", this.responseText); if (this.status === 200) { if (this.responseText.trim() !== "") { const responseData = parseResponse(this.responseText.trim()); console.log("解析结果:", responseData); if (responseData && responseData.details?.emailSentStatus === "true") { form.reset(); const successEl = form.querySelector(".send-success"); if (successEl) { successEl.style.display = "block"; } } else { const errorEl = form.querySelector(".send-error"); if (errorEl) { errorEl.style.display = "block"; } } } } else { console.error("请求失败,状态码:", this.status); const errorEl = form.querySelector(".send-error"); if (errorEl) { errorEl.style.display = "block"; } } } } }) }
内容的提问来源于stack exchange,提问作者Priyo Guideline
相关产品推荐
相关产品推荐

