问卷星开放文档

问卷星开放文档


答卷提交后跳转推送

<p>[TOC]</p> <h1>一、接口功能应用场景</h1> <p>在问卷设置》跳转设置》跳转到指定页面设置跳转目标的URL,并且开启“POST答卷数据到该地址”的功能。就可以实现:填写者在提交答卷后,跳转到这个指定的<code>URL</code>页面,并且系统会同步将该填写者作答的数据<code>POST</code>到该<code>URL</code>页面。</p> <p>应用场景:在填写者提交答卷后,可以跳转到用户自己的系统页面,并且作答信息(通过接口获取到的)作为页面元素显示在自己系统页面。如:考试问卷如果不想使用问卷星提供的标准成绩单,可以使用该功能,自己写一个成绩单页面作为跳转页面。</p> <h1>二、页面目标地址</h1> <p>使用页面目标地址需要注意以下问题:</p> <p>1、该地址需保证外网可访问的状态;</p> <p>2、该地址需要承载填写者提交答卷后的跳转落地页,所以需保证合适的页面内容;</p> <p>3、数据将以表单的方式<code>POST</code>到该地址,需要增加开发代码以读取<code>form</code>表单数据的<code>content</code>内容。</p> <h1>三、POST答卷数据</h1> <p>POST答卷数据会将每个填写者作答的数据,在其点击“提交”时推送到“页面目标地址”。每个填写者点击提交,就会执行一次推送操作;</p> <h2>1、推送机制</h2> <p>1) 用户在问卷设置界面设置跳转到指定页面,并勾选“POST答卷数据到该地址”; <img src="https://www.showdoc.com.cn/server/api/attachment/visitfile/sign/0ea85d6913438e43fa79fcf49e3941c9" alt="" /> 2) 如果需要获取问卷内容,可同时勾选“POST问卷内容到该地址”。如果未显示此选项,请联系客服顾问开通权限;</p> <p>3) <code>POST</code>答卷数据到跳转的指定页面的方式,与数据推送<code>API</code>方式只能二选一,推荐使用<code>POST</code>答卷数据到跳转的指定页面;这种方式的实时效性、稳定性更强;</p> <p>用户在提交完答卷后,问卷星将直接跳转到指定的页面并将答卷数据放在<code>POST</code>消息体中;</p> <p>跳转到用户指定页面后,用户指定页面可以同时读取到<code>GET</code>和<code>POST</code>的内容;</p> <h2>2、数据加密</h2> <p>考虑到答卷数据传输的安全性,推送的答卷数据进行了<code>AES</code>加密,加密密钥可以在设置界面获取到;</p> <p>解密方法如下:</p> <pre><code class="language-csharp">1)读取推送的BASE64数据为byte[] encryptedData; 2)取AES加解密密钥作为AES解密的KEY 3) 取byte[] encryptedData的前16位做为IV; 4)取第16位后的字节数组做为待解密内容; 5)解密模式使用CBC(密码块链模式); 6)填充模式使用PKCS #7(填充字符串由一个字节序列组成,每个字节填充该字节序列的长度); 7)使用配置好的实例化AES对象执行解密; 8)使用UTF-8的方式,读取二进制数组得到原始数据</code></pre> <p>示例代码(C#)</p> <pre><code class="language-csharp">//1)读取推送的BASE64数据为byte[] encryptedData; byte[] encryptedData = Convert.FromBase64String(encrypted); if (encryptedData == null || encryptedData.Length &lt; 17) return null; //2)取AES加解密密钥作为AES解密的KEY; byte[] key = Encoding.UTF8.GetBytes(aesKey); //3) 取byte[] encryptedData的前16位做为IV; byte[] iv = encryptedData.Take(16).ToArray(); //4)取第16位后的字节数组做为待解密内容; encryptedData = encryptedData.Skip(16).ToArray(); using (var aes = new RijndaelManaged()) { //5)解密模式使用CBC(密码块链模式); aes.Mode = CipherMode.CBC; //6)填充模式使用PKCS #7(填充字符串由一个字节序列组成,每个字节填充该字节序列的长度); aes.Padding = PaddingMode.PKCS7; aes.Key = key; aes.IV = iv; var cryptoTransform = aes.CreateDecryptor(); //7)使用配置好的实例化AES对象执行解密 byte[] r = cryptoTransform.TransformFinalBlock(encryptedData, 0, encryptedData.Length); //8)使用UTF-8的方式,读取二进制数组得到原始数据 return Encoding.UTF8.GetString(r); }</code></pre> <p>示例代码(java)</p> <pre><code class="language-java">import sun.misc.BASE64Decoder; import java.util.Arrays; import javax.crypto.Cipher; import javax.crypto.spec.IvParameterSpec; import javax.crypto.spec.SecretKeySpec; public class AesUtils { private static String ALGO = "AES"; private static String ALGO_MODE = "AES/CBC/NoPadding"; public static String aesDecrypt(String encryptedData, String securityKey) { try { byte[] data = (new BASE64Decoder()).decodeBuffer(encryptedData); byte[] iv = Arrays.copyOfRange(data, 0, 16); Cipher cipher = Cipher.getInstance(ALGO_MODE); SecretKeySpec keySpec = new SecretKeySpec(securityKey.getBytes("utf-8"), ALGO); IvParameterSpec ivSpec = new IvParameterSpec(iv); cipher.init(Cipher.DECRYPT_MODE, keySpec, ivSpec); byte[] countent = Arrays.copyOfRange(data, 16, data.length); byte[] original = cipher.doFinal(countent); String originalString = new String(original); return originalString.trim(); } catch (Exception e) { e.printStackTrace(); return null; } } } </code></pre> <h2>3、推送内容及格式</h2> <p>1、推送内容存储在表单(<code>application/x-www-form-urlencoded</code>)的<code>content</code>字段中; 2、<code>content</code>字段的值为经过<code>aes</code>加密后的<code>base64</code>字符串,解密后的内容包括答卷数据以及问卷数据; 3、答卷数据:推送内容及格式与数据推送<code>API</code>相同,参见:<code>https://www.wjx.cn/help/help.aspx?helpid=407&amp;h=1</code></p> <p>4、问卷数据:推送内容及格式与问卷开放<a href="https://www.showdoc.com.cn/wjxopenapi/7556919558404006" title="API[1000001]">API[1000001]</a>接口相同;</p> <h1>DEMO</h1> <h2>1、demo地址:</h2> <p><code>https://www.wjx.cn/demo/activityredirect.aspx?aes=822861f9c5114dc2bda214cd9567d0dc</code>注:aes=为AES解密密钥</p> <h2>2、示例代码(C#):</h2> <pre><code class="language-csharp">public partial class demo_activityredirect : System.Web.UI.Page { string aeskey = ""; string content = string.Empty; protected void Page_Load(object sender, EventArgs e) { content = Request.Form["content"]; aeskey = Request.QueryString["aes"]; Response.Write("推送的加密内容[content]:" + Receive()); Response.End(); } //接收推送消息 protected string Receive() { try { if (!string.IsNullOrEmpty(content) &amp;&amp; !string.IsNullOrEmpty(aeskey)) { content = Wjx.Common.Encrypt.Aes.Decrypt(content, aeskey); return content; } return "读取内容为空"; } catch (Exception e) { return "出错啦!\r\n" + e.Message; } } }</code></pre>

页面列表

ITEM_HTML