欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  后端开发

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

程序员文章站 2022-04-19 20:09:36
...

根据企业号开发者文档的发送消息接口消息数据格式,要想向企业号成员发送消息必须用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的问题,我没法看到返回成功或失败的信息
javascript - 微信企业号:如何POST JSON数据发送消息给企业号成员

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

';
  var_dump($_POST);
  echo "
"; ?>

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

array(0) {}

如果我把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数据根本无法用表单方式提交?

回复内容:

根据企业号开发者文档的发送消息接口消息数据格式,要想向企业号成员发送消息必须用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的问题,我没法看到返回成功或失败的信息
javascript - 微信企业号:如何POST JSON数据发送消息给企业号成员

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

';
  var_dump($_POST);
  echo "
"; ?>

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

array(0) {}

如果我把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的。