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

使用DocuSign API(Node.js)创建可签署HTML文档时遇请求体错误

解决DocuSign创建可签署HTML文档时的INVALID_REQUEST_BODY错误

运行项目时应用崩溃,返回错误信息:

"errorCode":"INVALID_REQUEST_BODY","message":"The request body is missing or improperly formatted. Unexpected character encountered while parsing value: {. Path 'documents[0].htmlDefinition.source', line 1, position 123."

相关代码

依赖引入与核心调用

const docusign = require("docusign-esign");
const fs = require("fs");

let envelope = await makeEnvelopeHtml(name, email);
let results = await envelopesApi.createEnvelope(accountId, {envelopeDefinition: envelope});

信封构建函数

async function makeEnvelopeHtml(name, email){
   
   let signer = docusign.Signer.constructFromObject({
      email: email,
      name: name,
      recipientId: "1",
      routingOrder: "1",
      roleName: "Signer",
   });

   let recipients = docusign.Recipients.constructFromObject({
    signers: [signer]
   });

   let html = 'template.html';

   let htmlDefinition = new docusign.DocumentHtmlDefinition();
   htmlDefinition.source = getHTMLDocument(html, name, email);

   let document = new docusign.Document();
   document.name="doc1.html";
   document.documentId="1";
   document.htmlDefinition=htmlDefinition;

   let env = new docusign.EnvelopeDefinition();
   env.emailSubject = "Signing Document with HTML";
   env.documents = [document];
   env.recipients = recipients;
   env.status = "sent";
    
   return env;
}

HTML内容处理函数

async function getHTMLDocument(html, name, email){
   let docHTMLContent = fs.readFileSync(html, {encoding: "utf8"});
   let content = docHTMLContent
   .replace("{signerName}", name)
   .replace("{signerEmail}", email)
   .replace("/sn1/", "<ds-signature data-ds-role=\"Signer\"/>")
   .replace("/sn1/", "<input data-ds-type=\"number\"/>")
   .replace("/l2q/", "<input data-ds-type=\"number\"/>");

   return content;
}

template.html内容

<html><head><meta charset="utf-8"></head><body>{signerName} {signerEmail} /sn1/ /l1q/ /l2q/ </body></html>

错误原因与修复方案

核心错误原因

报错指向htmlDefinition.source解析异常,因为getHTMLDocument是异步函数,但调用时未添加await,导致source被赋值为Promise对象而非实际HTML字符串,JSON序列化时出现格式错误。

另外存在两个次要问题:

  1. 两次替换/sn1/,会把签名标签覆盖成数字输入框,丢失签名区域;
  2. template.html中的/l1q/占位符未被替换,会残留到最终HTML中。

修复步骤

  1. 修复异步调用:在makeEnvelopeHtml中调用getHTMLDocument时添加await:
// 修改前
htmlDefinition.source = getHTMLDocument(html, name, email);
// 修改后
htmlDefinition.source = await getHTMLDocument(html, name, email);
  1. 修正替换逻辑:先修改template.html中的占位符(比如把第二个/sn1/改成/num1/),再调整替换代码:
let content = docHTMLContent
.replace("{signerName}", name)
.replace("{signerEmail}", email)
.replace("/sn1/", "<ds-signature data-ds-role=\"Signer\"/>")
.replace("/num1/", "<input data-ds-type=\"number\"/>")
.replace("/l1q/", "<input data-ds-type=\"text\"/>") // 按需设置输入类型
.replace("/l2q/", "<input data-ds-type=\"number\"/>");

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.15 16:07:18