首页 / 开发文档 / 留言板与自定义表单

留言板与自定义表单

留言表单怎么写,CSRF 令牌、蜜罐字段、验证码、提交间隔限制这一整套防刷是怎么配合的。

适用范围:单页(联系我们)、详情页、任意需要访客提交的地方。

留言表单

<form method="post" action="{naicha:url type="message"}" data-guard="1">
  <input type="hidden" name="_token" value="{naicha:token}">
  <input type="hidden" name="form" value="contact">

  <!-- 蜜罐:正常人不会填这一栏,填了就判定为机器人 -->
  <div style="position:absolute;left:-9999px">
    <input type="text" name="website" tabindex="-1" autocomplete="off">
  </div>

  <input type="text" name="name" required>
  <textarea name="content" required></textarea>
  <button type="submit">提交</button>
</form>

四个要点:

  • _token 是 CSRF 令牌,缺了会被直接拒绝;
  • website 是蜜罐字段,用 CSS 藏起来而不是 type="hidden" —— 隐藏域会被机器人识破;
  • data-guard="1" 让前端脚本做提交频率限制;
  • form 的值要和后台定义的表单名对上(默认 contact)。

自定义表单 {naicha:form}

<!-- 后台「表单」里定义过 contact,这里直接输出整张表单 -->
{naicha:form name="contact"}

<!-- 没定义过时退回内置表单,循环体里可用两个变量自己排 -->
{naicha:form name="contact"}
  <form method="post" action="{form.action}">
    <input type="hidden" name="_token" value="{naicha:token}">
    <input type="text" name="{form.name}">
  </form>
{/naicha:form}
形态行为
后台定义过这个表单直接输出后台配好的整张表单,循环体被忽略
后台没定义退回内置表单,循环体里可用 {form.name} {form.action}

验证码 {naicha:captcha}

<form method="post">
  <input type="hidden" name="_token" value="{naicha:token}">
  <input type="text" name="name" placeholder="称呼">
  {naicha:captcha}
  <button type="submit">提交</button>
</form>

站点没开验证码时输出空串,所以模板不用判断开关 —— 开了就有、没开就没有。后台不做这类判断:模板里有没有这个标签是一回事, 服务端要不要校验是另一回事(服务端只认设置开关)。

防刷机制一览

机制作用
CSRF 令牌阻止第三方站点伪造你的身份提交
蜜罐字段拦掉大部分表单机器人
提交间隔限制同一来源的两次提交之间强制间隔
登录失败限流15 分钟内失败 5 次即临时锁定该账号 + IP
图形验证码可在设置里开启,进一步抬高自动化成本

{naicha:messages} —— 前台留言列表

留言以前只在后台看得见。要把已收到的留言列出来(做"留言板"那类页面),用这个:

{naicha:messages num="20" form="contact"}
  <div class="msg">
    <b>{msg.name}</b>
    <span>{msg.when}</span>
    <p>{msg.content}</p>
  </div>
{/naicha:messages}
form只看哪张表单收到的(默认全部)
num列几条,默认 20
{msg.id} {msg.form} {msg.created_at} {msg.date} {msg.when}编号 / 表单名 / 时间
{msg.你表单里的字段名}表单里填了什么就能取什么,比如 {msg.name} {msg.contact} {msg.content}
⚠️ 这些是访客提交的原始内容,默认输出会被转义(安全)。 别对它用 html="1" —— 那等于让访客往你页面上写 HTML。

⚠️ 留言可能带**姓名、电话、邮箱**。列出来之前想清楚: 这个页面是给所有人看的,还是只给你自己看的。

{naicha:mycomments} —— 我的评论

当前登录会员自己发过的评论(含待审的 —— 那是他自己的东西,看得见才安心)。 放在会员中心或任意登录可见的位置:

{naicha:mycomments num="20"}
  <div>
    <span>{mycomment.when}</span>
    <a href="/detail/{mycomment.content_id}">{mycomment.content}</a>
  </div>
{/naicha:mycomments}

字段与 {naicha:commentlist} 完全一致,前缀换成 {mycomment.…}。 未登录时输出空串,所以模板不用自己判断登录。

没找到答案? 可以在 联系我们 留言说明使用场景,我们会补充进文档。