首页 > 微信企业号:如何POST JSON数据发送消息给企业号成员

微信企业号:如何POST JSON数据发送消息给企业号成员

根据企业号开发者文档的发送消息接口消息数据格式,要想向企业号成员发送消息必须用POST方式将JSON数据发送到指定的包含ACCESS_TOKEN的URL。

我想实现的是每隔一段时间间隔,查询数据库之后根据查询结果向特定成员发送消息。

我在自己的linux服务器的shell上通过编写curl命令已经可以成功地POST JSON数据,我自己的手机上也接到了信息,说明我对文档的理解和数据格式没有问题。但是这种方式必须把获取到的ACCESS_TOKEN HARD CODE到命令行中,而且TOKEN是有时限的,所以只能用来测试,不能用于生产环境中。

在生产环境中,我想的解决方案还是编写PHP/JAVASCRIPT程序来发送消息,然后在服务器端用CRON JOB来定时执行该PHP程序。但是由于对POST原理理解的不够到位,具体实现过程中碰到许多问题。

首先,如果只考虑可行性的话,能否用jQuery的ajax方法来实现呢?
在我的实验中,我先用PHP获取了正确的TOKEN,构建了URL,然后将URL值传递给了javascript 变量url,在console中尝试

$.ajax({
  type: "POST",
  url: url,
  data: '{"touser":"Jacklyn","msgtype":"text","agentid":23,"text":{"content":"test message"}}',
  success: function(){},
  dataType: "json",
  contentType : "application/json"
});

console返回了一个cross domain的错误,我理解因为cross domain的问题,我没法看到返回成功或失败的信息

但我的手机上也没有收到任何消息,所以发送应该是失败了。为了查看以上代码究竟发送了什么数据,我用另外一个文件来接收数据:

<?php
  echo '<pre>';
  var_dump($_POST);
  echo "</pre>";

 ?>

但是在$.ajax返回的对象.responsText里可以看到POST的结果是

<pre>array(0) {}</pre>

如果我把AJAX方法中的datetype和contenttype去掉,在responseText中就能看到正确的数据。所以,第一个问题是,如果$.ajax发送的JSON格式的数据不能被$_POST接收到,在服务器端应如何读取发送的数据呢?

此外,我读了一些关于POST的文档,如果没有理解错的话,实际上POST传递的信息由两部分组成,一是HEADER,一是DATA;我也搜寻了一些关于如何通过PHP POST JSON数据的文章,读的不是很懂,似乎大部分文章都是说要先对HEADER进行一定程度的控制,然后才能POST JSON,这是不是意味着用javascript就无法实现呢?

最后,我用以下函数

function gotoUrl(path, params, method) {
  //Null check
  method = method || "post"; // Set method to post by default if not specified.

  // The rest of this code assumes you are not using a library.
  // It can be made less wordy if you use one.
  var form = document.createElement("form");
  form.setAttribute("method", method);
  form.setAttribute("action", path);

  //Fill the hidden form
  if (typeof params === 'string') {
      var hiddenField = document.createElement("input");
      hiddenField.setAttribute("type", "hidden");
      hiddenField.setAttribute("name", 'data');
      hiddenField.setAttribute("value", params);
      form.appendChild(hiddenField);
  }
  else {
      for (var key in params) {
          if (params.hasOwnProperty(key)) {
              var hiddenField = document.createElement("input");
              hiddenField.setAttribute("type", "hidden");
              hiddenField.setAttribute("name", key);
              if(typeof params[key] === 'object'){
                  hiddenField.setAttribute("value", JSON.stringify(params[key]));
              }
              else{
                  hiddenField.setAttribute("value", params[key]);
              }
              form.appendChild(hiddenField);
          }
      }
  }

  document.body.appendChild(form);
  form.submit();
}

模拟一个表单提交数据,然后我尝试

gotoUrl(url,'{"touser":"shenkwen","msgtype":"text","agentid":23,"text":{"content":"test message"}}')

给url加上一个debug=1参数的话,可以看到postdata,以上代码的postdata是这样的:

data=%7B%22touser%22%3A%22shenkwen%22%2C%22msgtype%22%3A%22text%22%2C%22agentid%22%3A23%2C%22text%22%3A%7B%22content%22%3A%22test+message%22%7D%7D

看起来是把json字符串urlencode了,这是不是意味着在这个场合中所要求的json数据根本无法用表单方式提交?


contentType也可以指定为 urlencode的。

【热门文章】
【热门文章】